Numpy数组之间进行运算时,通常是逐元素之间进行运算,这通常要求数组具有相同的形状。而“广播(Broadcasting)”机制降低了这个限制,只需要满足一定的条件,形状不同的数组也可以进行运算,小数组会自动"广播"成和大数组相同的形状,完成运算。
文章目录
- 一、广播的含义
- 二、广播规则
- 2.1 可广播的前提
- 2.2 广播示例
一、广播的含义
广播是一种让不同形状数组间可以进行运算的机制。例如,一维数组a和标量b进行运算:
python">import numpy as np
a = np.array([1,2,3])
b = 2
a * b
图示如下,numpy会先检查标量b是否能广播成数组a的形状(此例可以),则numpy会将b"广播"成和a形状相同的一维数组,然后逐元素进行运算。注意这个广播只是一个逻辑上的操作,numpy并不会真正创建一个和a形状相同的数组b:
通过广播机制,此例在效果上等价于下面代码,a和b是形状相同的数组,逐元素进行运算:
python">import numpy as np
a = np.array([1,2,3])
b = np.array([2,2,2])
a * b
二、广播规则
上面的示例只是最简单的一维数组和标量,为了演示广播是什么。实际运算中,运算的参与者可能是多维数组,且维度可能不同。
2.1 可广播的前提
多维数组之间是否可以通过广播进行运算,需要逐位比较它们的形状(array.shape属性),从最末位开始,每个对应的位必须满足下面条件:元素数量相同或其中一个是1。
例如一个三维数组a的形状是(a1, a2, a3),它和一个二维数组b,形状是(b1, b2),从末尾开始逐位比较,即a3和b2比较,a2和b1比较:
- a3=b2 或 a3,b2至少有一个为1
- a2=b1 或 a2,b1至少有一个为1
当上面2个条件都满足时,则a和b是可广播的,运算最后的结果为三维数组,每位上的元素个数取a,b对应位上的最大值,即最终形状是(a1, max(a2,b1), max(a3,b2))。
2.2 广播示例
假设a的形状是(4,3,1),b的形状是(1,2),那么最终运算结果的形状就是(4,max(3,1),max(1,2)),即(4,3,2):
python">a = np.arange(12).reshape(4,3,1)
b = np.arange(2).reshape(1,2)
c = a * b
c.shape
假设b的形状是(2,2),那么在形状的倒数第二位上,a是3,b是2,它们即不相等,也不满足其中一个是1,这两个形状是无法广播的,强行运算会报无法广播的错误:
python">a = np.arange(12).reshape(4,3,1)
b = np.arange(4).reshape(2,2)
c = a * b