我有一个代码,我需要处理一些大的numpy数组。例如,我有一个3D数组A
,我需要使用B
的元素构建另一个3d数组A
。但是B
的所有元素都是相互独立的。例如:
for i in np.arange(Nx):
for j in np.arange(Ny):
for k in np.arange(Nz):
B[i][j][k] = A[i+1][j][k]*np.sqrt(A[i][j-1][k-1])
如果我可以平行构建B
数组,那么它将会极大地加速。在python中执行此操作的最简单方法是什么?
我也有类似的矩阵运算,比如标准化2D数组的每一行。实施例
for i in np.arange(Nx):
f[i,:] = f[i,:]/np.linalg.norm(f[i,:])
如果每行并行运行,它也会加速。怎么办呢?
答案 0 :(得分:2)
您应该查看Numpy's roll
函数。我认为这相当于你的第一个代码块(虽然你需要决定边缘发生了什么 - roll
“回绕”):
B = np.roll(A,1,axis=0) * np.sqrt(np.roll(np.roll(A,-1,axis=1),-1,axis=2))
第二种情况的另一个相当可怕的单行内容是:
f /= np.sqrt(np.sum(f**2, axis=1))[...,np.newaxis]
这一行的解释:
我们首先要计算每一行的规范。让我们
f = np.random.rand(5,6)
对f
f**2
对沿轴1的方块求和,使该轴“变平”。
np.sum(f**2, axis=1)
取平方和的平方根。
np.sqrt(np.sum(f**2, axis=1))
我们现在拥有每一行的规范。
要正确划分f
的每个原始行,我们需要使用Numpy广播规则来有效地添加维度:
np.sqrt(np.sum(f**2, axis=1))[...,np.newaxis]
最后我们计算结果
f /= np.sqrt(np.sum(f**2, axis=1))[...,np.newaxis]
答案 1 :(得分:0)
如果你正在好好照顾边缘,那么第一次矢量化的标准方法就是这样:
B = np.zeros(A.shape)
B[:-1, 1:, 1:] = A[1:, 1:, 1:] * np.sqrt(A[:-1, :-1, :-1])
然后,您需要使用适当的值填充B[-1, :, :]
,B[:, 0, :]
和B[:, :, 0]
。
将其扩展到其他索引应该非常简单。
答案 2 :(得分:0)
要在numpy
中执行并行处理,您应该查看mpi4py。它是Python的MPI绑定。它允许分布式处理。