在 numpy 中广播数组

broadcasting arrays in numpy

我得到了一个数组并将其重塑为以下维度:(-1,1,1,1) 和 (-1,1):

 Array A:
[-0.888788523827  0.11842529285   0.319928774626  0.319928774626  0.378755429421  1.225877519716  3.830653798838]

A.reshape(-1,1,1,1):
[[[[-0.888788523827]]]


 [[[ 0.11842529285 ]]]


 [[[ 0.319928774626]]]


 [[[ 0.319928774626]]]


 [[[ 0.378755429421]]]


 [[[ 1.225877519716]]]


 [[[ 3.830653798838]]]]

A.reshape(-1,1):
[[-0.888788523827]
 [ 0.11842529285 ]
 [ 0.319928774626]
 [ 0.319928774626]
 [ 0.378755429421]
 [ 1.225877519716]
 [ 3.830653798838]]

然后我做了减法和广播进来,所以我的结果矩阵是 7x1x7x1。

我很难想象广播的中间步骤。我的意思是我无法想象数组的哪些元素被重复以及它们在广播时的样子。 有人可以阐明这个问题吗?

In [5]: arr = np.arange(4)
In [6]: A = arr.reshape(-1,1,1,1)
In [7]: B = arr.reshape(-1,1)
In [8]: C = A + B
In [9]: C.shape
Out[9]: (4, 1, 4, 1)
In [10]: A.shape
Out[10]: (4, 1, 1, 1)
In [11]: B.shape
Out[11]: (4, 1)

有2个基本广播规则:

  • 扩展尺寸以匹配 - 通过在开始处添加尺寸 1 尺寸
  • 调整尺寸 1 的所有尺寸以匹配

所以在这个例子中:

 (4,1,1,1) + (4,1)
 (4,1,1,1) + (1,1,4,1)    # add 2 size 1's to B
 (4,1,4,1) + (4,1,4,1)    # adjust 2 of the 1's to 4
 (4,1,4,1)

第一步可能是最令人困惑的。 (4,1) 扩展为 (1,1,4,1),而不是 (4,1,1,1)。该规则旨在避免歧义 - 通过以一致的方式扩展,不一定是人类直觉上想要的。

想象一下两个数组都需要扩展才能匹配的情况,并且它可以在任一方向添加一个维度:

 (4,) and (3,)
 (1,4) and (3,1)  or (4,1) and (1,3)
 (3,4)            or (4,3)
 confusion

规则要求程序员选择向右展开的是 (4,1) 还是 (3,1)。 numpy 然后可以明确地添加另一个。


举个简单的例子:

In [22]: A=np.arange(3).reshape(-1,1)
In [23]: B=np.arange(3)
In [24]: C = A+B   (3,1)+(3,) => (3,1)+(1,3) => (3,3)
In [25]: C
Out[25]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])
In [26]: C.shape
Out[26]: (3, 3)

存在 [0,2,4],但在 C 的对角线上。

像这样广播时,结果是一种outer总和:

In [27]: np.add.outer(B,B)
Out[27]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])