我有两个numpy
的 ndarrays
a.shape # -> (3, 3)
b.shape # -> (5,)
我想计算一个c
数组,由
c.shape # -> (3, 3, 5)
c[...,i] = a*b[i]
(c
的确切形状并不重要,因为我总是可以转置它的轴)。
在我看来,到目前为止发布我的编码尝试会不必要地尴尬,这就像a[:,None,:]*b[None,:]
的许多变体,这就足够了,不是吗?
我怀疑np.einsum()
可能是答案,但其下标命令的语法在我头顶飞过......
一个不错的解决方案是使用出色的einsum
函数:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> b = np.array([10, 100, 1000, 10000, 100000])
>>> c = np.einsum('ij,k->ijk', a, b)
>>> c[1, 2, 3]
60000
>>> a[1, 2]
6
>>> b[3]
10000
我喜欢它,因为它使转换ij,k -> ijk
非常明确。同样可能,更简洁的是使用简单的广播:
>>> c = a[:, :, None] * b[None, None, :]
>>> c.shape
(3L, 3L, 5L)
如果使用:
来使用维度,则None
沿维度进行广播。
解决方案是使用np.outer
,因为基本上我们在那里执行外部产品。现在,np.outer
期望输入1D
数组,并且在预处理步骤中,它会在执行元素乘法之前展平输入。因此,np.outer(a,b)
的输出将是2D
的,我们需要将其重塑为所需的3D
形状。因此,最终的实现看起来像这样 -
np.outer(a,b).reshape(a.shape+(-1,))
更明确的重塑方法是这样的——
np.outer(a,b).reshape(a.shape+b.shape)