jk's notes
  • NumPy 快速开始

NumPy 快速开始

参考文档链接

1. 预备

需要熟悉 Python 基本语法, 同时需要安装 matplotlib 库.

本指南主要介绍 numpy 中的数组. 描述 n 维的表示, 以及如何参与运算. 同时介绍 axis, shape 等属性.

本指南结束后:

  1. 理解 NumPy 中的 1 维, 2 维, 以及 n 维数组.
  2. 不使用循环, 如何进行 n 维数组的线性代数运算.
  3. 理解 n 维数组的 axis 与 shape 属性.

2. 基础

NumPy 的主要对象是齐次 n 维数组 (homogeneous multidimensional array).

  1. 它是一张元素表, 通常元素是数字.
  2. 元素的类型均相同.
  3. 使用非负数字元组作为索引.

在 NumPy 中维度被称为 axes.

例如, 用数组描述一个 3D 空间的点, 可以使用 [1,2,1], 它就有一个轴 (axis), 这个 axis 中含有 3 个元素, 因此我们称其长度是 3. 而下面的示例中, 数组有两个 axes, 第一个 axis 的长度为 2, 第二个 axis 的长度为 3.

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

所以 轴 的计数 是从外 往内的.

NumPy 的数组类是 ndarray. 也被称为 array. 需要注意的是, 它与 Python 内置的不同. Python 内置的数组仅表示一维数组, 并且功能相对单一. narray 的重要属性有:

属性含义
ndarray.ndim表示数组的轴数(维度).
ndarray.shape表示数组的维度. 它是一个整数元素构成的元组. 其数字表示每一个维度的长度. 例如一个 n 行 m 列的矩阵, 其 shape 就是 (n,m). 而元组元素的个数, 表示轴数 (ndim).
ndarray.size数组中元素的个数, 其值与 shpape 各分量的乘积相等.
ndarray.dtype一个对象, 用于描述数组元素的类型. 可以使用 Python 的类型来指定, 也可以使用 NumPy 提供的类型, 例如 numpy.int16, numpy.int32, 或者 numpy.float64 等.
ndarray.itemsize表示数组中每一个元素的字节大小. 例如一个 float64 的数组, 其每一个元素的字节数为 64/8 为 8, 即 itemsize 为 8. 其值也等于 ndarray.dtype.itemsize.
ndarray.data底层数据的数组表示, 一般不会使用到该属性. 通常会使用索引工具来访问.

2.1 案例

import numpy as np
a = np.arange(15).reshape(3, 5)
b = np.array([6, 7, 8])

然后依次打印出 a, a.shape, a.ndim, a.dtype.name, a.itemsize, a.size, type(a), 以及 type(b).

reshape 函数用来修改数组的 shape.

2.2 创建数组

创建数组的方法有很多种. 首先可以基于 Python 的数组来创建, 然后将数组传入 np.array() 方法中得到 ndarray.

常见的错误: 调用 np.array() 时, 传入多余 1 个的参数. 该方法接收数组, 而不是一个个元素.

array 方法可以接收元素为数组的数组, 它自动会将其转换为 高维 数组.

在创建的时候, 可以通过 dtype=类型 来指定元素类型 (问题是哪些类型可以使用).

import numpy as np
a = np.array([2, 3, 4])
b = np.array([(1.5, 2, 3), (4, 5, 6)])
c = np.array([[1, 2], [3, 4]], dtype=complex)

通常数组元素是未知的, 但是元素的个数是可以知道的. 因此 NumPy 提供了一些辅助函数来创建具有占位符的数组. 他们分别是:

函数名描述
np.zeros(<shape>)按照指定 shape 生成数组, 并将元素初始化为 0.
np.ones(<shape>)按照指定 shape 生成数组, 并将元素初始化为 1.
np.empty(<shape>)按照 shape 生成数组, 其元素值为内存中原有值, 不进行初始化.

元素的类型默认为 float64, 可以在创建时, 通过 dtype= 来指定.

另一个创建 ndarray 的方法是使用 arange 方法. 其参数与用法与 Python 的 range 方法一样.

a = np.arange(10, 30, 5)
b = np.arange(0, 2, 0.3)

当出现浮点数时, 由于计算精度问题, 无法精确计算出生成元素的数量. 因此可以使用 np.linspace() 来指定从 s 到 e 生成 n 个元素. 注意, 生成数据为闭区间.

a = np.linspace(0, 2, 9)
# => array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  ])

通常在绘制函数图像时会使用到该函数.

2.3 打印数组

默认数组的打印有一定格式:

  1. 最后一个轴从左往右打印.
  2. 倒数第二个轴从上往下打印.
  3. 其余的轴也是从上往下打印, 并且每一个轴用一个换行区分.

一维打印成行, 二维打印成矩阵, 三维打印成矩阵列表.

如果数组元素非常多, 打印时会忽略内部元素, 仅打印出矩阵边角处的数据.

如果要修改该默认行为, 打印完整数组. 执行下面代码:

np.set_printoptions(threshold=sys.maxsize)  # sys module should be imported

2.4 基本运算

  • 算术运算会作用到数组的每一个元素上, 并生成一个新的数组作为运算结果.
  • 乘法运算 (*) 有别与其他矩阵语言, NumPy 会将矩阵各位置的分量分别进行乘法运算. 要实现矩阵乘法, 可以使用 @ 或 .dot() 函数 (A @ B 或 A.dot(B)).
  • 复合运算符 (+=, *= 等) 则是修改原数组, 而非创建新数组.
  • 如果参与运算的两个数组类型不一样, 会向上自动转换.
  • 大部分一元运算会以方法的形式呈现. 例如聚合函数: sum(), min(), max() 等.
  • 默认情况下, 所有的运算作用与整个数组, 好比将数组看成一个列表, 依次对列表元素进行操作, 而不会考虑其 shape. 但是指定 axis, 那么会沿着该轴来进行运算.
>>> b = np.arange(12).reshape(3, 4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> 
>>> b.sum(axis=0)     # sum of each column
array([12, 15, 18, 21])
>>> 
>>> b.min(axis=1)     # min of each row
array([0, 4, 8])
>>> 
>>> b.cumsum(axis=1)  # cumulative sum along each row
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

关于指定轴对应处理的是什么元素这个比较抽象, 但也比较重要.

2.5 通用函数

Last Updated: 12/3/25, 5:53 PM
Contributors: jk