矢量化numpy赋值

时间:2014-05-21 14:42:13

标签: python arrays numpy

我通过在其他numpy数组中查找值来为numpy数组赋值。这些数组可能有不同的索引。这是一个例子:

import numpy as np
A=1; B=2; C=3; D=4; E=5
X = np.random.normal(0,1,(A,B,C,E))
Y = np.random.normal(0,1,(A,B,D))
Z = np.random.normal(0,1,(A,C))
Result = np.zeros((A,B,C,D,E))
for a in range(A):
    for b in range(B):
        for c in range(C):
            for d in range(D):
                for e in range(E):
                    Result[a,b,c,d,e] = Z[a,c] + Y[a,b,d] + X[a,b,c,e]

优化此代码的最佳方法是什么?我可以使用Result [a,b,c,d,:] = Z [a,c] + Y [a,b,d] + X [a,b,c,:]删除E for循环。但那么如何删除其余的循环?我还在考虑在分配之前可以操作X,Y,Z,因此它可以轻松地与Result的尺寸合并。必须有更优雅的方式。感谢您的提示。

1 个答案:

答案 0 :(得分:6)

以这种方式:

Result = Z[:,None,:,None,None] + Y[:,:,None,:,None] + X[:,:,:,None,:]

为了生成这个矢量化版本,我所做的就是将各种索引替换为XYZ,并使用完整的a,b,c,d,e样式索引,插入{{ 1}}找到缺失的索引。例如,None变为Y[a,b,d],其向量化为Y[a,b,None,d,None]

在numpy中,Y[:,:,None,:,None]的索引告诉数组假装它有一个额外的轴。这并没有改变数组的大小,但它确实改变了操作的广播方式,这就是我们需要的。查看numpy broadcasting docs了解详情。