我有一个形状为(2,76020,2)
的NumPy数组。基本上它由两列组成,每列包含76020行,每行有两个条目。
我想将每列乘以不同的权重,例如1
列3
和2
列5
。例如:
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]
如何编写此乘法?
答案 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,)
我们需要匹配m
和a
的形状,因此我们必须将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元素权重数组可以使用。