首页 > NumPy 阅读数:27

NumPy数组的运算

NumPy 的多维数组对象 (ndarray) 是一个快速而灵活的大数据集容器,它不仅具有矢量运算和复杂广播的能力,而且还具有对数组数据进行快速运算的标准数学函数。在 NumPy 中,数组可以不需要循环就可对数据进行批量运算,这称为矢量化,而不同形状的数组之间的运算,称为广播。同时,在 NumPy 中还包含有 ufunc 对象,该对象具有对数组数据进行快速运算的通用函数。本节将介绍数组的运算。

在 NumPy 中,数组可以直接进行加、减、乘、除、指数、求倒数、取相反数、位运算等运算,而不需要使用烦琐的 for 循环之类的算法,并且在除法运算时,遇到除数为0时,会自动提示无效运算,但是仍会将计算结果显示出来,无效值处用 NaN 或 inf 表示。

在数组运算中,相同形状的数组按元素级进行逐个元素运算,而不同形状的数组,则按广播机制进行计算,并且在数组运算后,将返回包含运算结果的新数组。

相同形状数组的运算

首先创建两个相同形状数组 arr_a 和 arr_b,现将它们分别进行加、减、乘、除、取相反数、平方和按位异或运算。观察其输出结果,发现两个数组的运算就是将这两个数组中索引相同的元素进行运算。如果是一个数组的运算,则是将数组中的所有元素都进行相同运算。例如计算数组平方,就是将数组中每个元素都进行平方运算。

其示例代码 example1 如下。
# -*- coding: UTF-8 -*-
import numpy as np
#先创建两个相同形状的数组arr_a,arr_b
arr_a = np.arange(4)
arr_b = np.array([0,1,1,0])
print('两个相同形状数组arr_a,arr_b相加:')
arr_c = arr_a + arr_b
print(arr_c,'=',arr_a,'+',arr_b)
print('两个相同形状数组arr_a,arr_b相减:')
arr_c = arr_a - arr_b
print(arr_c,'=',arr_a,'-',arr_b)
print('两个相同形状数组arr_a,arr_b相乘:')
arr_c = arr_a * arr_b
print(arr_c,'=',arr_a,'*',arr_b)
print('两个相同形状数组arr_a,arr_b相除:')
arr_c = arr_a / arr_b
print(arr_c,'=',arr_a,'/',arr_b)
print('数组arr_a相反数:')
print(-arr_a)
print('数组arr_a的平方:')
print(arr_a**2)
print('数组arr_a的按位异或:')
print(arr_a^2)

不同形状数组的运算(广播机制)

当两个数据的形状(shape)不一致时,低维数组会自动将维度扩充到与高维数组一致,然后再按元素逐个运算,这就是数组的广播机制。为了更好地使用广播机制,需要遵循4个原则。

1) 让所有的输入数组向其中 shape 最长的数组看齐,shape 中不足的部分通过在前面加 1 补齐。

2) 输出数组的 shape 是输入数组 shape 的各个轴上的最大值。

3) 如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为 1,则这个数组能够用来计算,否则会报错。

4) 当输入数组的某个轴的长度为 1 时,沿着此轴计算时使用此轴上的第一组值。

下面通过示例观察不同形状数组的运算。

例如,先创建 2 行 3 列的数组 arr_a=np.arange(6).reshape(2,3) 和 1 行 3 列的数组 arr_b=np.arange(3),现将这两个数组相加。由于这两数组的维度不相同,当两数组相加时,低维的 arr_b 数组会自动向高维以复制的方式进行扩充,即复制 arr_b 第 1 行的元素到第 2 行,arr_b 扩充为 2 行 3 列数组,如下所示:

[[0,1,2]
 [0,1,2]]


其示例代码 example2 如下。
# -*- coding: UTF-8 -*-
import numpy as np
arr_a = np.arange(6).reshape(2,3)      #创建2行3列数组
arr_b = np.arange(3)                   #创建1行3列数组
arr_c = arr_a + arr_b                    #两个数组相加
print(arr_c,'=',arr_a,'+',arr_b)

然后,这两个数组再按元素逐个运算,运行结果如下:

[[0 2 4]    [[0 1 2]    [[0 1 2]
 [3 5 7]] =  [3 4 5]] + [0 1 2]]

数组和标量之间的运算

在 NumPy 中,数组的运算称为矢量化。大小相等的数组之间的任何算术运算都将应用到元素级。标量是只有大小没有方向的数据,数组和标量之间的算术运算就是将这个标量值传播到数组的各个元素,即将数组中的每个元素都与标量进行运算。

例如,创建 2 行 3 列的数组 arr=np.arange(6).reshape(2,3),现在计算 arr-1,其中 1 就是标量,则 arr-1 相当于将 arr 数组中的每个元素都减去标量值 1。