人人都会AI编程

20.1 NumPy:数值计算基础、多维数组、矩阵运算、广播机制

更新时间:2026-07-12

NumPy(Numerical Python)是 Python 数据科学生态的基石。几乎所有高阶库(Pandas、Matplotlib、scikit-learn、PyTorch)内部都依赖 NumPy 的数组结构。没有 NumPy,用原生 Python 做数值计算会又慢又麻烦。

为什么需要 NumPy

Python 的列表很灵活,但存大量数值时有两个致命缺陷:

  • 速度慢:列表里每个元素都是完整 Python 对象,内存开销大,运算靠 Python 循环。
  • 缺少向量化操作:要算两个列表对应元素相加,必须写 [a[i]+b[i] for i in range(n)],复杂运算更是繁琐。

NumPy 提供了 ndarray(N 维数组),本质是一块连续内存上的同类型数据块。由底层 C 语言实现,运算在编译层完成,速度比纯 Python 循环快 10 到 100 倍。

核心:ndarray 多维数组

创建数组极简单:

import numpy as np

a = np.array([1, 2, 3])           # 一维数组
b = np.array([[1, 2], [3, 4]])    # 二维数组(矩阵)

常用快捷创建方式:

np.zeros((3, 4))       # 全 0 数组
np.ones((2, 3))        # 全 1 数组
np.arange(10)          # 类似 range,生成 [0..9]
np.linspace(0, 1, 5)   # 等间距 5 个数

数组有形状(shape)和数据类型(dtype),可以任意切片、变形:

arr = np.arange(12).reshape(3, 4)  # 变为 3 行 4 列
print(arr[1, 2])                   # 取第 2 行第 3 列元素
print(arr[:, 1:3])                 # 取所有行,第 2 到 3 列

矩阵运算与通用函数

NumPy 让数学运算像操作数字一样自然:

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
a + b        # [5, 7, 9]  逐元素加法
a * b        # [4, 10, 18] 逐元素乘法(不是矩阵乘法!)
a @ b        # 32,点积运算
np.dot(a, b) # 同上,矩阵乘法用 @ 或 dot

矩阵乘法:

A = np.array([[1, 2], [3, 4]])
B = np.array([[2, 0], [1, 3]])
A @ B        # [[4, 6], [10, 12]]

此外有丰富的通用函数(ufunc),直接对整个数组做数学操作:

np.sqrt(a)   # 开方
np.sin(a)    # 正弦
np.sum(a)    # 求和
np.mean(a)   # 平均值
np.std(a)    # 标准差

这些函数比写循环简洁很多,且底层用 C 优化。

广播机制

广播是 NumPy 最强大的特性之一:形状不同的数组进行运算时,NumPy 会自动扩展数组的维度,让它们形状匹配,而无需复制数据
广播规则很简单:从尾部维度开始比较,如果两个维度相等,或其中一个是 1,就认为兼容;缺失的维度自动补 1 并扩展。
典型场景:

# 一个标量和数组相加
a = np.array([1, 2, 3])
a + 10    # [11, 12, 13]  标量被广播成与 a 同形状

# 矩阵加行向量
A = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([10, 20, 30])
A + b     # [[11, 22, 33], [14, 25, 36]]  行向量广播到每一行

# 列向量加行向量
c = np.array([[1], [2]])   # 形状 (2,1)
d = np.array([10, 20, 30]) # 形状 (3,)
c + d     # 形状 (2,3)
# 结果:[[11, 21, 31],
#        [12, 22, 32]]

广播避免了显式写循环,让代码高效且易读。它的核心口诀:“形状从右对齐,要么相等,要么为 1”

实际应用基础

  • 数据存储:机器学习中特征矩阵通常就是二维 NumPy 数组。
  • 图像处理:图像读取为 (height, width, channels) 的三维数组,可以直接切片、过滤、变换。
  • 数学建模:解线性方程组 np.linalg.solve(A, b),求特征值 np.linalg.eig,信手拈来。

掌握 NumPy 的数组思维——用整体操作替代逐个元素循环——是数据科学 Python 化的第一步,也是后续学习 Pandas 和 scikit-learn 的必经之路。