numpy中的并行数组操作

时间:2013-02-20 17:14:50

标签: python numpy parallel-processing

我有一个代码,我需要处理一些大的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,:])

如果每行并行运行,它也会加速。怎么办呢?

3 个答案:

答案 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绑定。它允许分布式处理。