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 的必经之路。