如何对执行 n 数组的元素明智乘法的 for 循环进行矢量化?

How to vectorize a for loop doing an element wise multiplication of n arrays?

我想获得一个数组,其中包含 n>2 数组的逐元素乘法。具体来说,有没有办法在 numpy 中向量化下面的示例代码(这里 n=3,但我通常需要对 n>=3 执行此操作)?

p1=np.array([0.5,0.2,0.3])

p2=np.array([0.3,0.1,0.6])

p3=np.array([0.8,0.1,0.1])

p=np.zeros((p1.shape[0],p2.shape[0],p3.shape[0] ))
for i in range(p1.shape[0]):
    for j in range(p2.shape[0]):
        for k in range(p3.shape[0]):
           p[i,j,k] = p1[i]*p2[j]*p3[k]

您正在寻找 outer 产品。首先执行 p1p2 的外积,然后是 p3 的外积。可以根据需要进行整形

prod = np.outer(np.outer(p1, p2), p3)

prod = prod.reshape((p1.shape[0],p2.shape[0],p3.shape[0] ))

编辑:@Yann Vernier 在下面的评论中建议的通用解决方案

from functools import reduce
ps = [p1, p2, p3]
prod = reduce(np.outer, ps).reshape([p.shape[0] for p in ps])

# array([[[0.12 , 0.015, 0.015],
#         [0.04 , 0.005, 0.005],
#         [0.24 , 0.03 , 0.03 ]],

#        [[0.048, 0.006, 0.006],
#         [0.016, 0.002, 0.002],
#         [0.096, 0.012, 0.012]],

#        [[0.072, 0.009, 0.009],
#         [0.024, 0.003, 0.003],
#         [0.144, 0.018, 0.018]]])

这是一个通用输入数组,使用 np.ix_ 使它们 outer-broadcastable 相互对抗 -

In [83]: A = [p1,p2,p3] # list of all input arrays

In [84]: np.multiply.reduce(np.ix_(*A))
Out[84]: 
array([[[0.12 , 0.015, 0.015],
        [0.04 , 0.005, 0.005],
        [0.24 , 0.03 , 0.03 ]],

       [[0.048, 0.006, 0.006],
        [0.016, 0.002, 0.002],
        [0.096, 0.012, 0.012]],

       [[0.072, 0.009, 0.009],
        [0.024, 0.003, 0.003],
        [0.144, 0.018, 0.018]]])