A.10 NumPy 基础知识

A.10 NumPy 基础知识

NumPy 是面向数据科学的非常方便的库。尤其是 NumPy 专用的数组(被称为 ndarray)中有很多方法,非常方便。在机器学习实现的过程中,向量和矩阵的计算频繁出现,使用 NumPy 的数组可以提高处理效率。

这里以第 5 章实现的源代码中出现的 NumPy 功能为中心,对其基础部分进行讲解。NumPy 的功能非常多,这里无法一一介绍,推荐有兴趣的读者上网查找资料,或者阅读相关书籍。

默认情况下,NumPy 没有被预置在 Python 标准库里,所以需要先进行安装。不过,如果是通过附录 A.8 介绍的 Anaconda 发行版安装的 Python,那么 NumPy 会被预置在内,不需要另行安装。

如果没有通过 Anaconda 发行版安装 Python,那 NumPy 基本上不会被预置在内,需要使用包管理工具 pip 来安装。

■ 在终端程序或命令提示符中输入(示例代码:A-10-1)

$ pip install numpy

NumPy 准备好之后,我们就一起通过实践来掌握它吧。首先在终端程序或命令提示符中输入 Python,启动交互式环境。

A.10.1 导入

要想能在 Python 中使用 NumPy,首先需要导入 NumPy。具体方法是利用 import 语句,像下面这样进行导入。

■ 以下全部在 Python 交互式环境执行(示例代码:A-10-2)

>>> import numpy as np

这一行的意思是以 np 这一名称读取 numpy 库。以后通过 np 这个名称就可以使用 NumPy 的功能。后面的示例代码都以已经完成库的读取为前提执行。

A.10.2 多维数组

NumPy 的核心是表示多维数组的 ndarray。在示例代码 A-9-9 中,我们已经见过 Python 使用“:”这个方便的切片写法,而 NumPy 的多维数组也有几个访问元素的方便写法,下面以本书用到的写法为中心予以介绍。

■ 示例代码:A-10-3

>>> # 创建3×3 的多维数组(矩阵) >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> >>> # 访问第1 行第1 列的元素 >>> # (注意:索引从0 开始) >>> a[0,0] 1 >>> >>> # 访问第2 行第2 列的元素 >>> a[1,1] 5 >>> >>> # 取出第1 列 >>> a[:,0] array([1, 4, 7]) >>> >>> # 取出第1 行 >>> a[0,:] array([1, 2, 3]) >>> >>> # 取出第2 列和第3 列 >>> a[:, 1:3] array([[2, 3], [5, 6], [8, 9]]) >>> >>> # 取出第2 行和第3 行 >>> a[1:3, :] array([[4, 5, 6], [7, 8, 9]]) >>> >>> # 取出第1 行,并赋给变量 >>> b = a[0] >>> b array([1, 2, 3]) >>> >>> # 也可以使用数组访问元素 >>> # 依次取出数组b 的第3 个和第1 个元素 >>> c = [2, 0] >>> b[c] array([3, 1])

此外,还可以像下面这样访问多维数组的基本属性。

■ 示例代码:A-10-4

>>> # 创建3×3 的多维数组(矩阵) >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> >>> # a 的维度。由于是矩阵,所以为二维 >>> a.ndim 2 >>> >>> # a 的形状。由于是3×3 矩阵,所以为(3, 3) >>> a.shape (3, 3) >>> >>> # a 的元素数。由于是3×3,所以元素数为9 >>> a.size 9

NumPy 的多维数组还支持数组间的合并。水平方向的合并使用 hstack,而垂直方向的合并使用 vstack。

■ 示例代码:A-10-5

>>> # 与3×1 的数组横向合并 >>> a = [[1], [2], [3]] >>> b = [[4], [5], [6]] >>> np.hstack([a, b]) array([[1, 4], [2, 5], [3, 6]]) >>> >>> # 与1×3 的数组纵向合并 >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> np.vstack([a, b]) array([[1, 2, 3], [4, 5, 6]])

通过 NumPy,还可以像下面这样使用 T 来获得转置矩阵。

■ 示例代码:A-10-6

>>> # 创建3×3 的多维数组(矩阵) >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> >>> # 对a 转置 >>> a.T array([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) A.10.3 广播

NumPy 中有一个功能用于数组元素间运算,称为广播。通常 NumPy 数组之间做运算时,数组的形状必须一致,但是在两个数组形状不一致却有可能调整为一致时,该功能就会先调整再进行运算。文字的说明可能不容易理解,下面通过示例来演示这个功能。

■ 示例代码:A-10-7

>>> # 创建3×3 的多维数组(矩阵) >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> >>> # 把a 的所有元素加10 >>> a + 10 array([[11, 12, 13], [14, 15, 16], [17, 18, 19]]) >>> >>> # 把a 的所有元素乘3 >>> a * 3 array([[ 3, 6, 9], [12, 15, 18], [21, 24, 27]])

这段代码在内部把 10 或 3 这样的数值当作 3×3 矩阵来处理,然后对每个元素进行运算(图 A-17)。

图 A-17

稍微提一句,这里的乘法运算不是矩阵的,而是每个元素的。这种对每个元素进行的运算被称为逐元素(element-wise)运算,矩阵的乘法与逐元素的乘法是不同的,这一点要注意。此外,还有这样的广播方式。

■ 示例代码:A-10-8

>>> # 分别把a 的每一列乘以2、3、4 >>> a * [2, 3, 4] array([[ 2, 6, 12], [ 8, 15, 24], [14, 24, 36]]) >>> >>> # 分别把a 的每一行乘以2、3、4 >>> a * np.vstack([2, 3, 4]) array([[ 2, 4, 6], [12, 15, 18], [28, 32, 36]])

这段代码在内部会像下面这样对数组进行扩展,然后对每个元素进行运算(图 A-18)。

图 A-18

 

上一章 封面 书架 下一章