上一篇文章我们介绍一下NumPy的导入、生成一维数组、数组算术运算和多维数组。下面我们学习NumPy的广播机制和如何访问数组元素等内容。
5 广播(broadcast )
NumPy中,形状不同的数组之间也可以进行运算。 之前的例子中,在2×2的矩阵 A和标量 10之间进行了乘法运算。在这个过程中,如下图所示,标量 10被扩展成了2 × 2的形状,然后再与矩阵 A进行乘法运算。这个巧妙
的功能称为广播(broadcast)。
我们通过下面这个运算再来看一个广播的例子。
In[28]: A = np.array([[1, 2], [3, 4]])
In[29]: B = np.array([10, 20])
In[30]: A * B
Out[30]:
array([[10, 40],
[30, 80]])
这个运算如下图所示:
可以看到一维数组B在运算时,触发广播机制,被“巧妙地”变成了和二维数组A相同的形状,然后再以element-wise的方式进行运算。
综上,广播(Broadcast)是 NumPy对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。
下面介绍一下广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
若条件不满足,抛出 "ValueError: frames are not aligned" 异常。
因为NumPy有广播功能,所以满足广播规则的不同形状的数组之间也可以顺利地进行运算 。
6 访问元素
元素的索引从0开始。对各个元素的访问可按如下方式进行。
In[31]: X = np.array([[51, 55], [14, 19], [0, 4]])
In[32]: print(X)
[[51 55]
[14 19]
[ 0 4]]
In[33]: X[0] # 第0行
Out[33]: array([51, 55])
In[34]: X[0][1] # (0,1)的元素
Out[34]: 55
也可以使用 for语句访问各个元素。
In[35]: for row in X:
...: print(row)
...:
[51 55]
[14 19]
[0 4]
除了前面介绍的索引操作, NumPy还可以使用flatten方法将当前数组转换为一维数组,再访问各个元素。
In[36]: X = X.flatten() # 将X转换为一维数组
In[37]: X
Out[37]: array([51, 55, 14, 19, 0, 4])
In[38]: X[np.array([0, 2, 4])] # 获取索引为0、 2、 4的元素
Out[38]: array([51, 14, 0])
运用这个标记法,可以获取满足一定条件的元素。例如,要从 X中抽出大于15的元素,可以写成如下形式。
In[39]: X > 15
Out[39]: array([ True, True, False, True, False, False])
In[40]: X[X > 15]
Out[40]: array([51, 55, 19])
对NumPy数组使用不等号运算符等(上例中是 X > 15),结果会得到一个布尔型的数组。上例中就是使用这个布尔型数组取出了数组的各个元素(取出 True对应的元素)。
以上就是学习NumPy的主要内容,下面我们将学习绘制图形库——Matplotlib。