广播是一种手段,可以让你的python代码段执行得更快。
1
将一个4 x 1向量和一个数字相加,Python会自动将这个数字展开变成一个1 x 4向量
这种广播,对列向量和行向量一样
2
将一个2 x 3矩阵加上一个1 x 3矩阵,Python会把第二个矩阵复制两次,变成2 x 3矩阵,然后让它们相加
一般情况下,将m x n矩阵加上1 x n矩阵,Python会复制1 x n矩阵m次,把它变成m x n矩阵,然后让它们相加
3
将2 x 3矩阵加上2 x 1矩阵,Python会水平复制3次,把它变成2 x 3矩阵,然后让它们相加
一般情况下,将m x n矩阵加上m x 1矩阵,Python会水平复制n次,把它变成m x n矩阵,然后让它们相加
通用规则
将 m x n矩阵 +,-,*,/ 一个1 x n矩阵,Python会把它复制m次变成m x n矩阵,然后逐个元素做加法,减法,乘法,除法
将 m x n矩阵 +,-,*,/ 一个m x 1矩阵,Python会把它复制n次变成m x n矩阵,然后逐个元素做加法,减法,乘法,除法
将m x 1矩阵其实是一个列向量 + ,-,*,/ 一个实数,Python会把这个实数复制m次变成m x 1矩阵,然后逐个元素做加法,减法,乘法,除法
类似的也适用于行向量
实例
下面列表是不同食物(每100g)中不同营养成分的卡路里含量表格,表格为3行4列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。那么,我们现在想要计算不同食物中不同营养成分中的卡路里百分比。
现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和 56+1.2+1.8=59,然后用56/59=94.9%算出结果。
对于其他食物,计算方法类似。首先,按列求和,计算每种食物中(100g)三种营养成分总和,然后分别用不用营养成分的卡路里数量除以总和,计算百分比。
定义A是一个3 x 4的矩阵。
1 | A = np.array([[56.0, 0.0, 4.4, 68.0], |
那么,能否不使用for循环完成这样的一个计算过程?我们可以使用python的numpy库完成这样的计算过程,分两步:
1、对每一列进行求和,可以看到输出的是每种食物(100g)的卡路里总和;
1 | cal = A.sum(axis=0) |
解释一下A.sum(axis = 0)中的参数axis。
axis用来指明将要进行的运算是沿着哪个轴执行,在numpy中,0轴是垂直的,也就是列,而1轴是水平的,也就是行。
axis = 0:在竖直方向求和
axis = 1:在水平方向求和
2、分别计算每种食物每种营养成分的百分比,将3 x 4的矩阵除以一个1 x 4的矩阵,得到一个3 x 4的结果矩阵,这个结果矩阵就是我们要求的百分比含量。
1 | percentage = 100 * A / cal.reshape(1,4) |
对于A/cal.reshape(1, 4)指令则调用了numpy中的广播机制。这里使用3×4的矩阵A除以1×4的矩阵cal。技术上来讲,其实并不需要再将矩阵cal.reshape(重塑)成1×4,因为矩阵cal本身已经是1×4了。但是当我们写代码时不确定矩阵维度的时候,通常会对矩阵进行重塑来确保得到我们想要的列向量或行向量。重塑操作reshape是一个常量时间的操作,时间复杂度是O(1), 它的调用代价极低。
广播能让你代码运行速度更快,能写更少的代码来实现你的目标。