广播是数组计算的利器。
多维数组计算本质还是二元计算,要求两个数组形状(shape)完全相同。 这是很苛刻的条件,对于高维数组更是十分麻烦。
我不太清楚「维度」到底指的哪个概念, 例如矩阵的形状是 (m,n),那么维度是二维还是 m 维 n 维? 为了避免混淆,还是用形状元组表达更合适。
广播机制解决了这一问题。 广播机制很简单,就是一个词:补齐。 形状符合特定规则的两个数组可以转换成相同形状的数组。
注意:向量是一维数组,例如 (5,) 虽然在形状上与二维数组 (5,1) 相似,但二者并不相同。
首先是补 1,使得两个数组的元组长度相等。
例如一维数组 (5,) 补成二维数组就是 (5,1),补成三维数组就是 (5,1,1)。 这一步具体实现各有不同,根据实验,MATLAB、Julia 都是向后补 1,numpy 是向前补 1。 向前补 1 就是 (5,) 补成 (1,5)、(1,1,5)。下面举例都使用向后补 1。
然后是补值,使得两个数组的元组每个元素都相等。 具体做法是从后向前比较(如果是向前补 1,那么这里是从前向后比较), 如果两个元素相等则该取值,如果其中一个为 1 则取另一个值, 否则无法广播,即使成整数倍关系也不行。
例如两个数组形状分别为 (1,2,3) 和 (5,),补 1 得到 (1,2,3) 和 (5,1,1), 补值得到 (5,2,3)。 再如两个数组形状分别为 (5,2) 和 (10,),补 1 得到 (5,2) 和 (10,1), 因为 5 != 10 而且都不为 1 所以无法广播。
关于 Julia 和 numpy 的差异,可以比较 (10,) 与 (1,5)、(5,1) 的运算, Julia 可以计算前者,不能计算后者:
| |
numpy 相反:
| |
参考文档: