Python 如何在使用append()时避免for循环
首先,我为自己是python和numpy的绝对初学者而道歉。请原谅我的无知 我有一个4D的压力测量立方体,其中的尺寸是(样本数量、时间、y轴、x轴),这意味着,对于每个样本,我有一个时空剖面的3D立方体。我需要收集这个3D立方体的压力读数(时间、y轴、x轴),并仅在坐标满足特定条件的情况下,将其存储到每个样本的数组中。在改变特定条件后,此数组的大小也会发生变化。因此,我必须使用append()来构建这个数组。但是,由于对于1000个示例,我必须使用for循环搜索每个示例的数百万个坐标,因此我编写的代码效率很低,运行时间很长(超过几个小时)。你能帮我写得更有效率吗 下面是我试图解决这个问题的代码。它工作得很好,给出了预期的结果,但速度非常慢Python 如何在使用append()时避免for循环,python,arrays,python-3.x,numpy,for-loop,Python,Arrays,Python 3.x,Numpy,For Loop,首先,我为自己是python和numpy的绝对初学者而道歉。请原谅我的无知 我有一个4D的压力测量立方体,其中的尺寸是(样本数量、时间、y轴、x轴),这意味着,对于每个样本,我有一个时空剖面的3D立方体。我需要收集这个3D立方体的压力读数(时间、y轴、x轴),并仅在坐标满足特定条件的情况下,将其存储到每个样本的数组中。在改变特定条件后,此数组的大小也会发生变化。因此,我必须使用append()来构建这个数组。但是,由于对于1000个示例,我必须使用for循环搜索每个示例的数百万个坐标,因此我编写
import numpy as np
# Number of sample points in x,y and t-axis
Nx = 101
Ny = 101
Nt = 100
n_train = 1000
target_array = []
for i_train in range (n_train):
for k in range (Nt):
for j in range (Ny):
for i in range (Nx):
if np.round(np.sqrt((i-np.round(Nx/2))**2+(j-np.round(Ny/2))**2)) == 2*k:
target_array.append(Pressure[i_train,k,j,i])
由于条件涉及索引,而不是4D数组的值,因此可以使用 这里
pp
是您的4D阵列:
iv, jv, kv = np.meshgrid(np.arange(pp.shape[3]), np.arange(pp.shape[2]), np.arange(pp.shape[1]))
selecting = np.round(np.sqrt((iv - np.round(pp.shape[3]/2))**2 + (jv - np.round(pp.shape[2]/2))**2)) == 2*kv
target = pp[:,selecting]
如果我正确理解了4D阵列的组织方式:
- 由
创建的数组保存索引,以选择三维x、y、t上的meshgrid
元素pp
是通过复制方程式创建的布尔数组,用于检查哪些坐标满足条件选择
是对target
的选择,在0轴上取满足其他3轴条件的所有元素(即pp
为真)选择
请注意,
target
是一个2D数组,若要使用1D数组,请使用target.flatte()
它是如何工作的?您覆盖了外部循环中的目标数组,因此最后它将只包含与i\u train=999
对应的值。非常抱歉,我从文件中复制代码时出错。我已经改正了。非常感谢您指出这一点。首先,您可以尝试在(内部)循环之外提取所有可能的(例如,np.round(Nx/2)
)操作。这将使您在时间上得到一些改进,但最大因数为10。然后您可以使用矢量化操作(np特定)将时间减少到秒(可能)。非常感谢您的建议。很抱歉我的无知,但请您详细解释一下这句话:“那么您可以使用矢量化操作(np特定)将时间缩短到秒(可能)”?@CristiFati的意思是您应该尝试使用numpy阵列的内置功能来执行矢量化操作,而不是依赖Python的for循环,后者的性能非常差。我会试着为你草拟一个解决方案。