通过标量乘以NumPy数组

时间:2016-04-10 16:55:24

标签: python arrays numpy

我有一个形状为(2,76020,2)的NumPy数组。基本上它由两列组成,每列包含76020行,每行有两个条目。

我想将每列乘以不同的权重,例如1325。例如:

m = 
[3,4][5,8]
[1,2][2,2]

a = [3,5]

我想:

[9,12][25,40]
[3,6][10,10]

我以为我可以将m * a乘以,但这给了我:

[9,20][15,40]
[3,10][6,10]

如何编写此乘法?

3 个答案:

答案 0 :(得分:3)

这是broadcasting的问题:你必须将尺寸对齐,这里是第二个:

m = array(
[[[3,4],[5,8]],
[[1,2],[2,2]]])
a = array([3,5])
print(a[None,:,None].shape, m*a[None,:,None])
"""
(1, 2, 1)

[[[ 9 12]
  [25 40]]

 [[ 3  6]
  [10 10]]]
"""  

答案 1 :(得分:2)

As @ B.M.说,这是一个'array broadcasting'问题。 (他的答案背后的想法是正确的,但我认为他和OP的尺寸没有正确匹配。)

>>> m = np.array([[[3,4],[5,8]],[[1,2],[2,2]]])
>>> print(m)
[[[3 4]
  [5 8]]

 [[1 2]
  [2 2]]]
>>> print(m.shape)
(2, 2, 2)
>>> a = np.array([3,5])
>>> print(a.shape)
(2,)

我们需要匹配ma的形状,因此我们必须将a'广播'到正确的形状:

>>> print(a[:, np.newaxis, np.newaxis].shape)
(2, 1, 1)
>>> b = a[:, np.newaxis, np.newaxis] * m
>>> print(b)
[[[ 9 12]
  [15 24]]

 [[ 5 10]
  [10 10]]]

通过这种方式,a的第一个维度将被保留,并映射到第一个维度m的每个元素。但是还有两个新的维度('轴')被创建为'广播'到m的另外两个维度。

注意:np.newaxis(字面意思)None,它们具有相同的效果。前者更容易理解正在发生的事情。另外,就标准术语而言,第一维(轴)通常称为“行”,第二维轴称为“列”。

答案 2 :(得分:1)

您的描述含糊不清

  

基本上它由两列组成,每列包含76020行,每行有两个条目。

(2,76020,2)中,哪个2是列,哪些是条目?

我相信你的m是(显示也是模棱两可的)

In [8]: m
Out[8]: 
array([[[3, 4],
        [5, 8]],

       [[1, 2],
        [2, 2]]])


In [9]: m*a
Out[9]: 
array([[[ 9, 20],
        [15, 40]],

       [[ 3, 10],
        [ 6, 10]]])

这与m*a[None,None,:]相同。广播时,numpy会根据需要自动添加尺寸。或者迭代地:

In [6]: m[:,:,0]*3
Out[6]: 
array([[ 9, 15],
       [ 3,  6]])

In [7]: m[:,:,1]*5
Out[7]: 
array([[20, 40],
       [10, 10]])

由于m(2,2,2)形状,我们无法判断哪个轴a应该相乘。

根据接受的答案,你想沿中轴相乘

In [16]: m*a[None,:,None]
Out[16]: 
array([[[ 9, 12],
        [25, 40]],

       [[ 3,  6],
        [10, 10]]])

但如果m形状为(2,3,2)怎么办? a必须有3个值

In [17]: m=np.array([[[3,4],[5,8],[0,0]],[[1,2],[2,2],[1,1]]])

In [18]: m*a[None,:,None]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-18-f631c33646b7> in <module>()
----> 1 m*a[None,:,None]

ValueError: operands could not be broadcast together with shapes (2,3,2) (1,2,1)

替代广播工作

In [19]: m*a[:,None,None]
Out[19]: 
array([[[ 9, 12],
        [15, 24],
        [ 0,  0]],

       [[ 5, 10],
        [10, 10],
        [ 5,  5]]])

In [20]: m*a[None,None,:]
Out[20]: 
array([[[ 9, 20],
        [15, 40],
        [ 0,  0]],

       [[ 3, 10],
        [ 6, 10],
        [ 3,  5]]])

现在,如果m具有不同的尺寸,例如(3,1000,2),我们可以一眼就看出一个2元素权重数组可以使用。