使用广播对 2D 和 3D 数组求和
Summing over 2D and 3D arrays using broadcasting
考虑以下 MWE:
import numpy as np
n=2
N = 6
a = np.random.randint(0,10,size=(N,1))
b = np.random.randint(0,10,size=(N,n))
c = np.random.randint(0,10,size=(n,N,5))
其中 c
例如(随机召回):
array([[[7 5 1 7 0]
[2 8 2 1 4]
[0 4 1 7 3]
[1 6 6 9 6]
[9 6 0 0 2]
[9 6 0 6 7]]
[[0 3 9 0 3]
[4 7 5 3 8]
[8 0 6 7 9]
[5 4 9 5 2]
[5 6 6 8 7]
[7 7 2 6 0]]])
形状为 (2,6,5)
.
我们从中制作:
out = a+b
>>>out
array([[ 9, 7],
[ 5, 7],
[ 7, 3],
[ 9, 9],
[15, 10],
[ 8, 9]])
形状为 (6,2)
.
现在我想做的是:我想将 out
的第一列添加到 c
的第一个矩阵(即矩阵由 c
),out
的第二列到 c
的第二列等等(你明白了)。目前,我正在尝试使用广播来做到这一点,但我似乎对自己感到困惑。
我想不使用循环,因为我的实际问题非常大。
期望输出:
>>>np.stack([out[:,i][:,np.newaxis] + c[i] for i in range(2)])
array([[[16, 14, 10, 16, 9],
[ 7, 13, 7, 6, 9],
[ 7, 11, 8, 14, 10],
[10, 15, 15, 18, 15],
[24, 21, 15, 15, 17],
[17, 14, 8, 14, 15]],
[[ 7, 10, 16, 7, 10],
[11, 14, 12, 10, 15],
[11, 3, 9, 10, 12],
[14, 13, 18, 14, 11],
[15, 16, 16, 18, 17],
[16, 16, 11, 15, 9]]])
形状为 (2,6,5)
.
尝试:
out[None, :,:] + c
这会导致以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-702-d54cfe51ec32> in <module>
----> 1 out[None, :,:] + c
ValueError: operands could not be broadcast together with shapes (1,6,2) (2,6,5)
将不胜感激。
您可以转置并添加一个维度,让广播来完成这项工作:
out.T[...,None]+c
说明:
.T
转置 out
(形状 (2,6)
)并且 [...,None]
添加一个额外的维度作为 out
的最新维度(现在 out
是形状(2,6,1)
)。最后,广播到 c
的形状 (2,6,5)
将根据需要将所有元素广播到 c
的深度。
要将 out
的列与 c
的“矩阵”“对齐”,您应该转置 out
,然后添加一个能够广播的维度,即:
import numpy as np
n=2
N = 6
a = np.random.randint(0,10,size=(N,1))
b = np.random.randint(0,10,size=(N,n))
c = np.random.randint(0,10,size=(n,N,5))
out = a+b
result = out.T[:, :, None] + c
完整性检查:
np.all(result == np.stack([out[:,i][:,np.newaxis] + c[i] for i in range(2)]))
True
考虑以下 MWE:
import numpy as np
n=2
N = 6
a = np.random.randint(0,10,size=(N,1))
b = np.random.randint(0,10,size=(N,n))
c = np.random.randint(0,10,size=(n,N,5))
其中 c
例如(随机召回):
array([[[7 5 1 7 0]
[2 8 2 1 4]
[0 4 1 7 3]
[1 6 6 9 6]
[9 6 0 0 2]
[9 6 0 6 7]]
[[0 3 9 0 3]
[4 7 5 3 8]
[8 0 6 7 9]
[5 4 9 5 2]
[5 6 6 8 7]
[7 7 2 6 0]]])
形状为 (2,6,5)
.
我们从中制作:
out = a+b
>>>out
array([[ 9, 7],
[ 5, 7],
[ 7, 3],
[ 9, 9],
[15, 10],
[ 8, 9]])
形状为 (6,2)
.
现在我想做的是:我想将 out
的第一列添加到 c
的第一个矩阵(即矩阵由 c
),out
的第二列到 c
的第二列等等(你明白了)。目前,我正在尝试使用广播来做到这一点,但我似乎对自己感到困惑。
我想不使用循环,因为我的实际问题非常大。
期望输出:
>>>np.stack([out[:,i][:,np.newaxis] + c[i] for i in range(2)])
array([[[16, 14, 10, 16, 9],
[ 7, 13, 7, 6, 9],
[ 7, 11, 8, 14, 10],
[10, 15, 15, 18, 15],
[24, 21, 15, 15, 17],
[17, 14, 8, 14, 15]],
[[ 7, 10, 16, 7, 10],
[11, 14, 12, 10, 15],
[11, 3, 9, 10, 12],
[14, 13, 18, 14, 11],
[15, 16, 16, 18, 17],
[16, 16, 11, 15, 9]]])
形状为 (2,6,5)
.
尝试:
out[None, :,:] + c
这会导致以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-702-d54cfe51ec32> in <module>
----> 1 out[None, :,:] + c
ValueError: operands could not be broadcast together with shapes (1,6,2) (2,6,5)
将不胜感激。
您可以转置并添加一个维度,让广播来完成这项工作:
out.T[...,None]+c
说明:
.T
转置 out
(形状 (2,6)
)并且 [...,None]
添加一个额外的维度作为 out
的最新维度(现在 out
是形状(2,6,1)
)。最后,广播到 c
的形状 (2,6,5)
将根据需要将所有元素广播到 c
的深度。
要将 out
的列与 c
的“矩阵”“对齐”,您应该转置 out
,然后添加一个能够广播的维度,即:
import numpy as np
n=2
N = 6
a = np.random.randint(0,10,size=(N,1))
b = np.random.randint(0,10,size=(N,n))
c = np.random.randint(0,10,size=(n,N,5))
out = a+b
result = out.T[:, :, None] + c
完整性检查:
np.all(result == np.stack([out[:,i][:,np.newaxis] + c[i] for i in range(2)]))
True