MENU

Broadcasting in Python

April 1, 2019 • Read: 211 • Deep Learning

上图是一张关于不同食物每100g中不同营养成分卡路里含量表,表格为3行4列,列表示不同的食物种类;行表示不同的营养成分

我们现在想要计算各种食物不同营养成分中卡路里百分比

首先计算苹果中碳水化合物卡路里的百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和56+1.2+1.8=59,然后用56/59=94.9%得到结果。可以看出苹果中的卡路里大部分来自于碳水化合物,而牛肉则不同

对于其他食物,计算方法类似。首先,按列求和,计算每种食物(100g)三种营养成分总和,然后分别用不同营养成分的卡路里数除以总和,计算出百分比

那么,能否不适用for循环完成计算呢?

假设上图的表格是一个4行3列的矩阵$A$,记为$A_{3\times 4}$,接下来我们用Python中的numpy库完成计算。核心代码只有两行,第一行代码完成对每一列进行求和,第二行代码分别计算每种食物每种营养成分的百分比

首先输入矩阵,如下图所示

然后使用下面的代码计算没列的和,可以看到输出的是每种食物(100g)的卡路里总和

其中sum的参数axis = 0表示求和运算按列执行

接下来计算百分比,下面的代码将$3\times 4$的矩阵除以一个$1\times 4$的矩阵,得到一个$3\times 4$的结果矩阵,这个结果矩阵就是我们要求的百分比含量

下面再来解释一下A.sum(axis = 0)中的参数axisaxis用来指明将要进行的运算是沿哪个轴执行,在numpy中,0表示垂直,也就是列,1表示水平,也就是行

A/cal.reshape(1,4)指令则调用了numpy中的广播机制。这里使用$3\times 4$的矩阵$A$除以$1\times 4$的矩阵$cal$,从技术上来讲,其实并不需要再将矩阵$cal$reshape(重塑)成$1\times 4$,因为矩阵$cal$本身已经是$1\times 4$了,但是当我们写代码时不确定矩阵维度的时候,通常会对矩阵进行重塑来确保得到我们想要的列向量或行向量

那么$3\times 4$的矩阵是怎么和$1\times 4$的矩阵做除法的呢?让我们来看一个例子

numpy中,当一个$4\times 1$的列向量与一个常数做加法时,实际上会将常数扩展为一个$4\times 1$的列向量,然后两者做逐元素加法

再看下一个例子


用一个$2\times 3$的矩阵和一个$1\times 3$的矩阵相加,其泛化形式是$m\times n$的矩阵和$1\times n$的矩阵相加。在执行加法操作时,其实是将$1\times n$的矩阵复制成为$m\ times n$的矩阵,然后两者做逐元素加法

下面是最后一个例子

这里相当于是一个$m\times n$的矩阵加上一个$m\times 1$的矩阵,在执行运算时,会先将$m\times 1$的矩阵水平复制$n$次,变成$m\times n$的矩阵,然后在执行逐元素加法

Archives Tip
QR Code for this page
Tipping QR Code