广播阵列操作

算术运算在 Numpy 数组上以元素方式执行。对于相同形状的数组,这意味着在相应索引处的元素之间执行操作。

# Create two arrays of the same size
a = np.arange(6).reshape(2, 3)
b = np.ones(6).reshape(2, 3)

a
# array([0, 1, 2],
#       [3, 4, 5])
b
# array([1, 1, 1],
#       [1, 1, 1])

# a + b: a and b are added elementwise
a + b
# array([1, 2, 3],
#       [4, 5, 6])

也可以通过 Numpy 广播在不同形状的阵列上执行算术运算。通常,一个阵列在另一个阵列上广播,以便在全等形状的子阵列上执行元素运算。

# Create arrays of shapes (1, 5) and (13, 1) respectively
a = np.arange(5).reshape(1, 5)
a
# array([[0, 1, 2, 3, 4]])
b = np.arange(4).reshape(4, 1)
b
# array([0],
#       [1],
#       [2],
#       [3])

# When multiplying a * b, slices with the same dimensions are multiplied
# elementwise. In the case of a * b, the one and only row of a is multiplied
# with each scalar down the one and only column of b.
a*b
# array([[ 0,  0,  0,  0,  0],
#        [ 0,  1,  2,  3,  4],
#        [ 0,  2,  4,  6,  8],
#        [ 0,  3,  6,  9, 12]])

为了进一步说明这一点,请考虑 2D 和 3D 阵列与全等子维度的乘法。

# Create arrays of shapes (2, 2, 3) and (2, 3) respectively
a = np.arange(12).reshape(2, 2, 3)
a
# array([[[ 0  1  2]
#         [ 3  4  5]]
#
#        [[ 6  7  8]
#         [ 9 10 11]]])
b = np.arange(6).reshape(2, 3)
# array([[0, 1, 2],
#        [3, 4, 5]])

# Executing a*b broadcasts b to each (2, 3) slice of a,
# multiplying elementwise.
a*b
# array([[[ 0,  1,  4],
#         [ 9, 16, 25]],
#
#        [[ 0,  7, 16],
#         [27, 40, 55]]])

# Executing b*a gives the same result, i.e. the smaller
# array is broadcast over the other.

何时应用阵列广播?

当两个阵列具有兼容的形状时进行广播。

从尾随形状开始逐个比较形状。如果两个维度相同或者其中一个是 1,则它们是兼容的。如果一个形状具有比另一个更高的尺寸,则不比较超出的部件。

兼容形状的一些示例:

(7, 5, 3)    # compatible because dimensions are the same
(7, 5, 3)

(7, 5, 3)    # compatible because second dimension is 1  
(7, 1, 3)

(7, 5, 3, 5) # compatible because exceeding dimensions are not compared
      (3, 5)

(3, 4, 5)    # incompatible 
   (5, 5) 

(3, 4, 5)    # compatible 
   (1, 5) 

这是关于阵列广播的官方文档。