Skip to content

第四章 NumPy ​

本章定位:NumPy 是 Python 科学计算的核心基础库,提供了高效的多维数组对象 ndarray 与丰富的数学运算函数,是数据分析、机器学习、信号处理等领域的工具基础。相比 Python 原生列表,NumPy 数组支持向量化运算,运算速度快、内存占用低,是数据方向 Python 学习的必备内容。

前置准备:使用前需安装 NumPy 库:pip install numpy 行业惯例导入方式:import numpy as np

学习目标:掌握 ndarray 数组的创建、索引、变形与运算,能使用 NumPy 完成基础的数值计算、统计分析与矩阵运算。


1 数组的创建与操作(ndarray) ​

NumPy 的核心是 ndarray(N-dimensional array)多维数组对象,所有数值运算都围绕数组展开。

1.1 创建数组 ​

1.1.1 从序列创建数组 ​

使用 np.array() 可以将 Python 原生的列表、元组等序列转换为 NumPy 数组,自动推断元素数据类型。

python
import numpy as np

# 从列表创建一维数组
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)
# 输出: [1 2 3 4 5]

# 从嵌套列表创建二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# 输出:
# [[1 2 3]
#  [4 5 6]]

# 指定数据类型创建
arr3 = np.array([1, 2, 3], dtype=np.float32)
print(arr3.dtype)  # float32

提示

np.array() 会自动统一数组内元素的数据类型;若同时存在整数和浮点数,会自动向上转换为浮点型。

1.1.2 快速创建特殊数组 ​

函数功能示例
np.arange(start, end, step)生成连续整数序列数组,左闭右开np.arange(0, 10, 2) → [0 2 4 6 8]
np.linspace(start, end, num)生成指定个数的均匀间隔数组np.linspace(0, 10, 5) → [ 0. 2.5 5. 7.5 10. ]
np.zeros(shape)生成指定形状的全零数组np.zeros((2, 3)) → 2行3列全0矩阵
np.ones(shape)生成指定形状的全一数组np.ones((3, 2)) → 3行2列全1矩阵
np.eye(n)生成 n 阶单位矩阵np.eye(3) → 3阶单位矩阵

1.2 数组元素索引与访问 ​

1.2.1 一维数组索引 ​

一维数组的索引、切片规则与 Python 列表高度兼容,同时支持整数数组索引(花式索引),可一次性选取多个位置的元素。

python
arr = np.array([10, 20, 30, 40, 50])

# 基础索引
print(arr[0])   # 10
print(arr[-1])  # 50

# 切片
print(arr[1:4])  # [20 30 40]

# 整数数组索引(花式索引)
index = [0, 2, 4]
print(arr[index])  # [10 30 50]

1.2.2 二维数组索引 ​

二维数组索引格式:arr[行索引, 列索引],行与列均支持切片、整数数组索引,全选对应维度用冒号 : 表示。

python
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]])

# 获取单个元素:第0行第1列
print(arr[0, 1])  # 2

# 切片:获取所有行,第1列
print(arr[:, 1])  # [2 5 8]

# 切片:获取第1-2行,第0-1列
print(arr[1:3, 0:2])
# [[4 5]
#  [7 8]]

# 布尔索引:筛选大于5的元素
print(arr[arr > 5])  # [6 7 8 9]

1.2.3 笛卡尔积索引 np.ix_() ​

np.ix_() 可以实现多维度索引的笛卡尔积组合,一次性获取多个交叉位置的元素。

python
arr = np.array([[1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]])

# 获取 (0,1)、(0,3)、(-1,1)、(-1,3) 四个位置的元素
print(arr[np.ix_([0, -1], [1, 3])])
# [[ 2  4]
#  [10 12]]

1.3 数组核心属性 ​

属性说明示例结果
ndim数组的维度数(轴数)二维数组 → 2
shape数组的形状,格式为 (行数, 列数)2行3列 → (2, 3)
dtype数组元素的数据类型整数数组 → int64
size数组元素总个数2行3列 → 6
python
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim)    # 2
print(arr.shape)   # (2, 3)
print(arr.dtype)   # int64
print(arr.size)    # 6

1.4 数组形状处理 ​

1.4.1 reshape:重塑形状(返回副本) ​

reshape() 可以改变数组的形状,返回新数组副本,不修改原数组。参数 -1 表示自动计算该维度的大小。

python
arr = np.arange(6)  # [0 1 2 3 4 5]

# 重塑为 2行3列
arr2 = arr.reshape(2, 3)
print(arr2)
# [[0 1 2]
#  [3 4 5]]

# -1 自动计算维度
arr3 = arr.reshape(3, -1)
print(arr3.shape)  # (3, 2)

1.4.2 resize:重塑形状(修改原数组) ​

resize() 功能与 reshape 类似,但直接修改原数组本身(视图),无返回值。

python
arr = np.arange(6)
arr.resize(2, 3)
print(arr)
# [[0 1 2]
#  [3 4 5]]

1.4.3 ravel:多维展平为一维(返回视图) ​

ravel() 将多维数组展平为一维数组,返回原数组的视图,修改新数组会影响原数组。默认按行(C顺序)展平,order='F' 按列展平。

python
arr = np.array([[1, 2], [3, 4]])
print(arr.ravel())  # [1 2 3 4]

# 按列展平
print(arr.ravel(order='F'))  # [1 3 2 4]

1.4.4 flatten:多维展平为一维(返回副本) ​

flatten() 功能与 ravel 一致,但返回原数组的副本,修改新数组不会影响原数组。

python
arr = np.array([[1, 2], [3, 4]])
arr_flat = arr.flatten()
arr_flat[0] = 100
print(arr)  # 原数组不变
# [[1 2]
#  [3 4]]

补充:数组转置

二维数组可直接通过 .T 属性获取转置数组:

python
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.T)
# [[1 4]
#  [2 5]
#  [3 6]]

1.5 数组的堆叠与拼接 ​

将多个数组合并为一个数组,分为纵向堆叠和横向堆叠两种方向。

函数作用规则
np.row_stack() / np.vstack()纵向(垂直方向)堆叠所有数组的列数必须相同
np.column_stack() / np.hstack()横向(水平方向)拼接所有数组的行数必须相同
np.concatenate(arr_list, axis=0)按指定轴拼接axis=0纵向,axis=1横向
python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])

# 纵向堆叠
print(np.vstack([arr1, arr2]))
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# 横向拼接
print(np.hstack([arr1, arr2]))
# [[1 2 5 6]
#  [3 4 7 8]]

# 通用拼接函数,axis=1 横向
print(np.concatenate([arr1, arr2], axis=1))

2 数组的基本运算 ​

NumPy 数组支持向量化运算,无需循环即可对所有元素批量执行运算,代码简洁且效率远高于原生列表循环。

2.1 算术运算 ​

支持 + - * / % // ** 等运算符,逐元素对应运算。

python
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

print(arr1 + arr2)  # [5 7 9]
print(arr1 * 2)     # [2 4 6]  标量广播
print(arr1 ** 2)    # [1 4 9]

广播机制

当运算双方形状不同时,NumPy 会自动触发广播机制,将维度少的数组自动扩展匹配维度。例如标量与数组运算、一维数组与二维数组运算,只要维度兼容即可自动广播。

2.2 比较运算 ​

支持 > >= < <= == != 比较运算符,返回相同形状的布尔数组。

python
arr = np.array([1, 3, 5, 7, 9])

# 比较运算,返回布尔数组
print(arr > 5)  # [False False False  True  True]

# 布尔索引:筛选满足条件的元素
print(arr[arr > 5])  # [7 9]

3 常用数学与统计函数 ​

NumPy 提供了丰富的统计函数,支持按指定轴(axis)计算。

axis 参数说明:

  • axis=0:按**垂直方向(列方向)**计算,跨行运算
  • axis=1:按**水平方向(行方向)**计算,跨列运算
  • 不指定 axis 时,对整个数组所有元素计算
函数功能
np.sum(arr, axis=None)求和
np.mean(arr, axis=None)求算术平均值
np.std(arr, axis=None)求标准差
np.var(arr, axis=None)求方差
np.min(arr, axis=None)求最小值
np.max(arr, axis=None)求最大值
np.argmin(arr, axis=None)求最小值的索引
np.argmax(arr, axis=None)求最大值的索引
python
arr = np.array([[1, 2, 3],
                [4, 5, 6]])

# 整个数组求和
print(np.sum(arr))  # 21

# 按列求和(axis=0)
print(np.sum(arr, axis=0))  # [5 7 9]

# 按行求均值(axis=1)
print(np.mean(arr, axis=1))  # [2. 5.]

4 线性代数基础运算 ​

NumPy 提供了基础的线性代数运算能力,满足基础矩阵计算需求。

4.1 特殊矩阵 ​

函数功能
np.zeros((m,n))m行n列全零矩阵
np.ones((m,n))m行n列全一矩阵
np.eye(n)n阶单位矩阵(对角线为1,其余为0)
np.diag(列表)根据列表生成对角矩阵;传入二维数组则提取对角线元素
python
# 3阶单位矩阵
print(np.eye(3))
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

# 提取矩阵对角线
arr = np.array([[1,2],[3,4]])
print(np.diag(arr))  # [1 4]

4.2 矩阵运算 ​

函数/运算符功能注意事项
np.dot(arr1, arr2) / arr1 @ arr2矩阵点积/乘法第一个数组的列数 = 第二个数组的行数
np.linalg.eig(arr)计算矩阵的特征值与特征向量返回(特征值数组, 特征向量数组)
np.linalg.solve(A, b)求解多元线性方程组 Ax = bA为系数矩阵,b为常数项向量
python
# 矩阵乘法
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(np.dot(A, B))
# [[19 22]
#  [43 50]]

5 伪随机数生成 ​

numpy.random 子模块提供了丰富的伪随机数生成功能,支持多种分布的随机数生成。

5.1 常用随机函数 ​

函数功能示例
np.random.rand(shape)生成[0, 1)均匀分布随机浮点数np.random.rand(2,3) → 2行3列随机数
np.random.randint(low, high, size)生成[low, high)随机整数np.random.randint(0, 10, size=5) → 5个0-9随机整数
np.random.randn(shape)生成标准正态分布随机数(均值0,方差1)np.random.randn(10) → 10个标准正态分布数
np.random.normal(loc, scale, size)生成指定均值、标准差的正态分布np.random.normal(100, 10, size=100)

5.2 随机种子 ​

使用 np.random.seed(种子值) 可以固定随机数生成器的状态,保证每次运行生成的随机数一致,便于结果复现与调试。

python
np.random.seed(42)
print(np.random.randint(0, 10, 5))
# 固定种子后,每次运行结果都为 [6 3 7 4 6]

本章练习 ​

基础题 ​

  1. 创建一个 3 行 4 列的全零数组,将第 1 行第 2 列元素修改为 10,输出数组与它的 shape、dtype、size。
  2. 使用 np.arange 生成 0~20 的整数数组,重塑为 4 行 5 列,计算所有元素的和、均值、标准差。
  3. 创建两个 2 行 3 列的随机整数数组(0~10),分别进行纵向堆叠与横向拼接,输出结果。
  4. 生成 100 个均值为 80、标准差为 10 的正态分布随机数,计算其中大于 90 的元素个数。

进阶题 ​

  1. 创建一个 5×5 的随机整数矩阵(10~99),提取它的主对角线元素,计算对角线元素的和。
  2. 求解二元一次方程组:$\begin{cases}2x + y = 7 \ x - 3y = -2 \end{cases}$,使用 np.linalg.solve 实现。
  3. 生成 1000 个 0~100 的随机整数,统计每个数字出现的次数。

本章常见易错点 ​

  1. 索引越界:数组索引从 0 开始,最大索引为 长度-1,超出范围会触发 IndexError。
  2. 形状不匹配:数组运算、堆叠时,对应维度长度不匹配会触发报错,堆叠前需确认维度。
  3. reshape 与 resize 混淆:reshape 返回副本不修改原数组,resize 直接修改原数组,注意区分使用场景。
  4. 视图与副本混淆:ravel 返回视图,修改会影响原数组;flatten 返回副本,互不影响,避免误用导致数据意外修改。
  5. axis 参数搞反:axis=0 是按列(纵向)计算,axis=1 是按行(横向)计算,注意不要混淆方向。

基于 Vite 强力驱动 | 纯静态轻量托管