【问题标题】:numpy broadcasting to each column of the matrix separatelynumpy 分别广播到矩阵的每一列
【发布时间】:2019-12-29 10:59:55
【问题描述】:

我必须矩阵:

a = np.array([[6],[3],[4]])
b = np.array([1,10])

当我这样做时:

c = a * b

c 看起来像这样:

[ 6, 60]
[ 3, 30]
[ 4, 40]

这很好。 现在,假设我向 a 添加了一列(为了示例,它是一个相同的列。但它必须是):

a = np.array([[6,6],[3,3],[4,4]])

b 保持不变。

我想要的结果是 2 个相同的 c 副本(因为列相同),沿新轴堆叠:

new_c.shape == [3,2,2]

如果你做new_c[:,:,0]new_c[:,:,1] 你会得到原始的c。 我尝试使用 np.expand_dims 向 a 和 b 添加新轴,但没有帮助。

【问题讨论】:

  • 第一种情况 a (3,1) * (2,) => (3,2)。第二,(3,2)*(2,)=>(3,2)*(1,2)=>(3,2)。你想要 (3,2,1)*(1,1,2)=(3,2,2)。 a[:,:,None] 应该可以解决问题。
  • 或者它的 (3,1,n)*(1,2,1)>(3,2n) a[:,None,:]*b[None,2,None]

标签: python numpy array-broadcasting


【解决方案1】:

一种方法是使用 numpy.einsum

>>> import numpy as np
>>> a = np.array([[6],[3],[4]])
>>> b = np.array([1,10])
>>> print(a * b)
[[ 6 60]
 [ 3 30]
 [ 4 40]]
>>> print(np.einsum('ij, j -> ij', a, b))
[[ 6 60]
 [ 3 30]
 [ 4 40]]
>>> a = np.array([[6,6],[3,3],[4,4]])
>>> print(np.einsum('ij, k -> ikj', a, b)[:, :, 0])
>>> print(np.einsum('ij, k -> ikj', a, b)[:, :, 1])
[[ 6 60]
 [ 3 30]
 [ 4 40]]
[[ 6 60]
 [ 3 30]
 [ 4 40]]

关于numpy.einsum的更多用法,我推荐:

Understanding NumPy's einsum

【讨论】:

    【解决方案2】:

    您在这里有多个选项,其中一个是使用numpy.einsum,如另一个答案中所述。另一种可能是使用数组reshape 方法:

    result = a.T.reshape((a.shape[1], a.shape[0], 1)) * b
    result = result.reshape((-1, 2))
    result 
    array([[ 6, 60],
           [ 3, 30],
           [ 4, 40],
           [ 6, 60],
           [ 3, 30],
           [ 4, 40]])
    

    然而,对我来说更直观的是通过np.vstack 将数组堆叠起来,每列a 乘以b,如下所示:

    result = np.vstack([c[:, None] * b for c in a.T])
    result
    array([[ 6, 60],
           [ 3, 30],
           [ 4, 40],
           [ 6, 60],
           [ 3, 30],
           [ 4, 40]])
    

    【讨论】:

      猜你喜欢
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      相关资源
      最近更新 更多