Numpy数组中的“广播”机制容许NumPy在算术运算期间可以处理具有不同形状的数组。根据某些规则,较小的数组可以在较大的数组上“广播”,以便它们具有兼容的形状。例如在对RGB图像进行归一化时,需要将每个通道的像素值从\(0-255\)压缩到\(0-1\),也就是将数组每个元素乘以\(1/255\),依据运算规则,假设图片形状为\(M\times N\times 3\),则需要一个形状也为\(M\times N \times 3\)的数组,数组每个元素都为\(1/255\)。这会浪费大量内存空间,其实只需要在循环中对图像中每个元素乘以\(1/255\)即可,这也正是广播内部的实现机制,可以减少复制元素所需的内存。如下图,可以理解为首先把最后一个维度“虚空”复制,变成\(1\rightarrow3\),然后拓展的最后一个维度的数据又复制三次变成\(3 \rightarrow 4\times 3\),然后\(4\times 3\rightarrow 4\times 4\times 3\)。
广播的规则
两个数组进行运算时,从最右端开始扫描两个数组的形状,需要满足以下条件才能进行广播。
- 维数不一定要求相同。
- 对应维度相等或者其中一个为1。
广播后的形状
- 输出数组的维数为两个数组最大的维数,不足的补1
- 输出数组的形状是输入数组形状的各个维度上的最大值。
以下是一些实例。
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 (3d array): 15 x 3 x 5
B (3d array): 15 x 1 x 5
Result (3d array): 15 x 3 x 5
A (3d array): 15 x 3 x 5
B (2d array): 3 x 5
Result (3d array): 15 x 3 x 5
A (3d array): 15 x 3 x 5
B (2d array): 3 x 1
Result (3d array): 15 x 3 x 5