广播阵列操作
算术运算在 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)
这是关于阵列广播的官方文档。