Python 广播—;将一个(NxN)数组乘以一个(M)数组得到一个(nxm)数组

Python 广播—;将一个(NxN)数组乘以一个(M)数组得到一个(nxm)数组,python,numpy,Python,Numpy,我有两个numpy 我想计算一个c数组,由 c.shape # -> (3, 3, 5) c[...,i] = a*b[i] (c的确切形状并不重要,因为我总是可以变换它的轴) 在我看来,到目前为止,发布我的编码尝试将是不必要的尴尬,这类似于a[:,None,:]*b[None,:]上的许多变体,这就够了,不是吗 我怀疑np.einsum()可能是答案,但它的subscripts命令的语法让我难以理解……一个很好的解决方案是使用奇妙的函数: >>> a = np.arr

我有两个
numpy

我想计算一个
c
数组,由

c.shape # -> (3, 3, 5)
c[...,i] = a*b[i]
(c的确切形状并不重要,因为我总是可以变换它的轴)

在我看来,到目前为止,发布我的编码尝试将是不必要的尴尬,这类似于
a[:,None,:]*b[None,:]
上的许多变体,这就够了,不是吗


我怀疑
np.einsum()
可能是答案,但它的subscripts命令的语法让我难以理解……

一个很好的解决方案是使用奇妙的函数:

>>> 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
沿维度广播。

一个好的解决方案是使用奇妙的函数:

>>> 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
希望输入是
1D
数组,作为预处理步骤,它在执行元素乘法之前将输入展平。因此,
np.outer(a,b)
的输出将是
2D
,我们需要将其重塑为所需的
3D
形状。因此,最终的实现看起来是这样的-

np.outer(a,b).reshape(a.shape+(-1,))
一种更明确的重塑方式如下所示-

np.outer(a,b).reshape(a.shape+b.shape)

另一种解决方案是使用,因为我们基本上是在那里执行外部产品。现在,
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)

我更喜欢你答案中的广播部分,我觉得这很有启发性(最后我发现了正确的模式!),但这两部分都是正确的,我得到了我的结果。。。非常感谢。我现在明白了我真正想要的和我想要的是
c.shape->(5,3,3)
,但是发现了模式(最后!)很简单,就像
a[None,:,:]*b[:,None,None]
-再次感谢你。
einsum
真的需要“啊哈!”当你意识到
a[i,j]*b[k]=c[i,j,k]
直接翻译成
einsum('ij,k->ijk',…)
。虽然有人可能会说,对于简单的广播来说,这太过分了,但我还是喜欢它……我更喜欢你答案中的广播部分,我发现它相当有启发性(最后我发现了正确的模式!),但这两部分都是正确的,我得到了我的结果。。。非常感谢。我现在明白了我真正想要的和我想要的是
c.shape->(5,3,3)
,但是发现了模式(最后!)很简单,就像
a[None,:,:]*b[:,None,None]
-再次感谢你。
einsum
真的需要“啊哈!”当你意识到
a[i,j]*b[k]=c[i,j,k]
直接翻译成
einsum('ij,k->ijk',…)
。虽然有人可能会说,对于简单的广播来说,这太过分了,但我还是喜欢它。。。