列向量与行向量做加减运算的“幕后真凶”:Broadcasting
2019-08-17 本文已影响0人
HerdingCat
根据网上关于广播机制[1]的介绍,能了解到何时numpy
会运行Broadcasting机制[2]。关于具体如何扩展两个矩阵维数并未展开叙述。本文将做对此进行补充,可将Broadcasting就是在其余层数相同的情况下,将低层向高层扩展成两个等大的ndarray
进行运算作为结论,以下为具体分析过程。
维数不一致
手册[2]中举例如下:
A (2d array): 5 x 4
B (1d array): 1
Result (2d array): 5 x 4
A (2d array): 5 x 4
B (1d array): 4
Result (2d array): 5 x 4
A (4d array): 8 x 1 x 6 x 1
B (3d array): 7 x 1 x 5
Result (4d array): 8 x 7 x 6 x 5
在这种情况下,低维向高位扩展。上述(5 x 4)
与(1 x )
运算时,可以看作B将唯一的元素填充在(5 x 4)
矩阵中,然后与A矩阵做运算;对于(5 x 4)
与(4 x )
的情况,可以看作B将5个(1 x 4)
的相同的向量按行拼接成(5 x 4)
,然后与A矩阵做运算。此处需要留意第二种情况下,除了缺省维数(或者维数为1)另外的维数必须相同!
例子
x = np.array([1, 2, 3]) # 可视为(1 x 3)
# y = np.array([[0, 1], [1, 2]]) # 此时维数为(2 x 2), 其中2与(1 x 3)中3不等,报错
# y = np.array([[0, 1], [1, 2], [2, 3]]) # 此时维数为(3 x 2),其中2与(1 x 3)中3不等,报错
# y = np.array([[[0, 1, 2], [1, 2, 3]], # 此时维数为(2 x 2 x 3),其中3与(1 x 3)中3相等,顺利运行
# [[2, 3, 4], [3, 4, 5]]])
y = np.array([[0, 1, 2], [1, 2, 3]])
z1 = x + y
z2 = y + x
print("x shape:", x.shape)
print("x:", x)
print("y shape:", y.shape)
print("y:", y)
print("z1 shape:", z1.shape)
print("z1:", z1)
print("z2 shape:", z2.shape)
print("z2:", z2)
以下为输出结果
# outputs
x shape: (3,)
x: [1 2 3]
y shape: (2, 3)
y:
[[0 1 2]
[1 2 3]]
z1 shape: (2, 3)
z1:
[[1 3 5]
[2 4 6]]
z2 shape: (2, 3)
z2:
[[1 3 5]
[2 4 6]]
维数一致
将维数不一致所给例子中x = np.array([1, 2, 3])
改为x = np.array([[1, 2, 3]])
即可得到维数相同的例子。
此时,更像是低层向高层扩展,一个直观的解释:将多个相同向量通过层数叠加变成一个矩阵。如果将维数不一致(维数缺省)的情况下将缺省维数作为1对待,则就转化成维数一致情况。因此,Broadcasting就是在其余层数相同的情况下,将低层向高层扩展成两个等大的ndarray
进行运算。