速通指南:把 NumPy 的 13 个核心章节浓缩成一条主线,全程用一个「全班 5 位同学 × 3 门课成绩表」串起来。看完就能直接上手处理 Excel 表格数据,深挖再看对应章节的独立文章。
NumPy 是什么?
NumPy(Numerical Python)是 Python 科学计算的基础库,核心是 ndarray(N 维数组)对象。
用 Python 自带的列表处理大量数值时,又慢又占内存;而 ndarray 把同类型的元素紧密排列在连续内存中,运算速度能快几十倍。它是 Pandas、SciPy、scikit-learn、深度学习框架等几乎所有数据科学工具的底层基石。
想用 Python 做数据处理、机器学习,NumPy 是绕不开的第一步。
🎯 本篇主线案例:班主任手上有 5 位同学、3 门课(语文/数学/英语)的成绩单。接下来每一节,我们都用这同一份数据来演示——学完你会发现,13 个知识点其实是一套连贯的"成绩处理流水线"。
1. 创建数组
一切的起点:怎么创建各种 ndarray。
import numpy as np
# 从列表创建:5 位同学 × 3 门课的成绩表(行=同学,列=语文/数学/英语)
scores = np.array([[90, 80, 85],
[60, 70, 65],
[95, 88, 92],
[72, 65, 78],
[55, 60, 70]])
# 特殊数组
zeros = np.zeros((2, 3)) # 全 0
ones = np.ones((2, 3)) # 全 1
arange = np.arange(0, 10, 2) # 等差数列,输出: [0 2 4 6 8]
linspace = np.linspace(0, 1, 5) # 等分,输出: [0. 0.25 0.5 0.75 1. ]
⚠️ 灵魂警告:Python 原生 int 是任意精度的,但 NumPy 数组默认用固定位宽的整数(64 位系统上一般是
int64)。当你把超大整数塞进数组,或者整型数组做除法时,结果可能静默溢出(32 位环境下尤其危险)。数据要精确、要算小数,请显式指定:np.array([...], dtype=np.float64)。
2. 数组属性
每个数组都有几个关键属性,决定它长什么样。
arr = np.array([[1, 2, 3], [4, 5, 6]])
arr.shape # 输出: (2, 3) 2 行 3 列
arr.ndim # 输出: 2 几维数组
arr.size # 输出: 6 元素总数
arr.dtype # 输出: int64 元素类型
💡
shape是最重要的属性:后面所有广播、统计的axis逻辑都跟它有关。看到数组先问一句"它 shape 是多少"。
3. 索引与切片
像列表一样索引,但支持多维,还有强大的"花式索引"。回到成绩表:第 1 位同学(索引 0)各科成绩是 [90, 80, 85]。
scores[0, 1] # 输出: 80 第 1 位同学(行0)的数学(列1)
scores[:, 1] # 输出: [80 70 88 65 60] 全班同学的数学成绩
scores[1, :] # 输出: [60 70 65] 第 2 位同学全部成绩
scores[::-1] # 输出: 把 5 行倒序
scores[[0, 2, 4], :] # 花式索引:只取第 1、3、5 位同学
⚠️ 灵魂警告(新手最大噩梦):切片返回的是视图(浅拷贝),不是副本!
reshape同理。修改视图会污染原数组:first = scores[0] # 视图 first[0] = 999 # ⚠️ scores[0,0] 也会变成 999!想得到一份独立的数据,务必用
.copy():safe = scores[0].copy()。凡是"我要单独改一份,不能影响原来的",都先.copy()。
4. 数组运算
逐元素运算,和普通数学符号几乎一致。给全班每门课都加 5 分平时分:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
a + b # 输出: [5 7 9]
a * b # 输出: [4 10 18]
a ** 2 # 输出: [1 4 9]
a > 2 # 输出: [False False True]
scores + 5 # 全班每门课都加 5 分(标量运算,见第 8 节广播)
5. 形状操作
重塑、展平、转置——调整数组的"长相"。
arr = np.arange(12)
arr.reshape(3, 4) # 输出: 3 行 4 列(元素总数不变)
arr.flatten() # 输出: 展平成一维
arr.T # 输出: 转置,行列互换
⚠️ 灵魂警告:
reshape返回的也是视图,与切片一样共享底层数据。确认元素总数(size)没变才能 reshape,否则报错。要独立副本用arr.reshape(3, 4).copy()。另外,转置
scores.T会让 shape 从(5, 3)变成(3, 5)——“行=同学、列=科目"变成"行=科目、列=同学”,做统计时方向完全不同,别搞混。
6. 通用函数(ufunc)
对数组逐元素应用数学函数,速度快(底层用 C 实现,比 Python 循环快几十倍)。
arr = np.array([1, 4, 9])
np.sqrt(arr) # 输出: [1. 2. 3.]
np.exp(arr) # 输出: 指数
np.log(arr) # 输出: 对数
💡 ufunc 都能配
where或out参数做"只算部分/就地写入",但那是进阶玩法。新手记住:凡是"对每个元素做同一个数学运算",先想到 ufunc,别写 for 循环。
7. 统计与聚合
求总和、均值、最大值,以及最重要的 axis 参数。回到成绩表:
np.sum(scores) # 输出: 总分(所有 15 个成绩相加)
np.mean(scores) # 输出: 平均分
np.mean(scores, axis=0) # 输出: [75.5 72.6 78. ] 每门课全班平均
np.max(scores, axis=1) # 输出: [90 70 95 78 70] 每位同学最高分
np.argmax(scores, axis=1) # 输出: [0 2 0 2 2] 每位同学最高分在哪科(0=语文)
💡
axis=0沿着行方向压缩(对每一"列"统计);axis=1沿着列方向压缩(对每一"行"统计)。记不住就记口诀:axis 指"要消掉的那一维"——axis=0消掉行 → 得到每列的结果。
8. 广播机制(重点 & 难点)
不同形状的数组也能运算——小的自动"扩展"到大的形状。给全班每门课加上各自的"难度加成":
scores + 10 # 标量广播:每个元素 +10
scores + np.array([5, 3, 4]) # 行广播:3 门课各加不同分 → 每行都加
广播是怎么"补形状"的?规则是从最后一个维度往前逐个对齐:
scores: (5, 3)
加成: (3,)
↑ 对齐到倒数第 1 维,都是 3,直接算
→ 加成自动变成 (5, 3),每行加同一份
scores: (5, 3)
加成2: (5, 1)
↑ 倒数第 1 维 1 ≠ 3,但 1 可以广播
→ 加成2 自动变成 (5, 3),每列加同一份
规则一句话:从最后一个维度往前比,维度相同直接算,维度为 1 则广播,都不匹配则报错。
⚠️ 灵魂警告:
(3,)和(1, 3)看着"差不多",但广播结果完全不一样——前者逐行加,后者逐列加(因为 1 在倒数第 1 维)。报ValueError: operands could not be broadcast together with shapes (5,3) (4,)时,别慌,就是最后对不齐,检查一下两个数组的shape。
9. 布尔索引与筛选
用条件筛选出想要的元素——数据处理的常用手法。找出不及格的同学:
scores < 60
# 输出: 每个元素是 True/False 的"掩码"
scores[scores < 60] # 输出: [55 ...] 所有不及格的分数
# np.where:条件成立取 x,不成立取 y —— 数据清洗高频场景
np.where(scores < 60, 0, scores) # 不及格的全改成 0
np.where 的多条件逻辑才是它最强的地方,配合 &(且)、|(或):
# 数学 60 分以上、且 语文 65 分以上的同学:留原分,否则置 0
math_col = scores[:, 1]
chinese_col = scores[:, 0]
np.where((math_col >= 60) & (chinese_col >= 65), scores, 0)
⚠️ 灵魂警告:用
&和|,不是 Python 的and/or(那个会报错:truth value of an array is ambiguous)。而且每个条件都要用括号包起来,否则优先级会出错。
10. 数组拼接与分割
把多个数组合并,或者把一个拆开。
a = np.array([1, 2])
b = np.array([3, 4])
np.concatenate([a, b]) # 输出: [1 2 3 4] 沿现有轴拼接
np.vstack([a, b]) # 输出: [[1 2] [3 4]] 垂直堆叠成两行
np.hstack([a, b]) # 输出: [1 2 3 4] 水平拼接
np.split(a, 2) # 输出: 分割成若干块
💡 拼成绩表:来了两位新同学,
np.vstack([scores, new_students])就能把新行追加进去。想加一门新课(新列)用np.hstack或np.column_stack。
11. 文件读写
把数组保存到磁盘,下次直接加载——处理完成绩单别忘了存档。
np.save("scores.npy", scores) # 保存单个数组(.npy 二进制)
loaded = np.load("scores.npy") # 加载,输出: shape 还是 (5, 3)
np.savez("data.npz", s=scores, b=b) # 保存多个数组(.npz 压缩)
⚠️ 灵魂警告:
np.load后拿到的数组记得确认dtype和shape没变(旧存档可能是别的版本生成的)。.npy存的是二进制,跨机器没问题;想给人看 / 给 Excel 用,用np.savetxt("scores.csv", scores, delimiter=",")。
12. 随机数
生成随机数组,可复现的种子。给全班生成一份模拟的体育成绩:
rng = np.random.default_rng(42) # 新版推荐接口,固定种子 42,结果可复现
rng.random((2, 3)) # 均匀分布 [0, 1)
rng.normal(70, 10, 5) # 正态分布:均值 70、标准差 10,输出 5 个
rng.integers(0, 10, 5) # 随机整数 [0, 10)
⚠️ 灵魂警告:请用
np.random.default_rng()(新版 Generator API),别再用np.random.random()/np.random.seed()(旧版)。新版基于 PCG-64 算法,随机质量更好、更快,而且天然支持并行(每个进程一个独立rng,不会互相干扰);旧版的np.random.seed()是全局状态,多线程/并行场景下极易踩坑。
13. 线性代数基础
矩阵乘法、求逆、解方程——科学计算的看家本领,也是最小二乘拟合的根基。
A = np.array([[1, 2], [3, 4]])
A @ A # 矩阵乘法(@ 或 np.matmul)——注意 A 得是方阵
np.linalg.inv(A) # 逆矩阵
np.linalg.det(A) # 行列式
np.linalg.eig(A) # 特征值 & 特征向量
真正的高频场景是解线性方程组(数据分析里的最小二乘法就是解这种方程):
# 例:3x + 2y = 8
# 2x - y = 3
A = np.array([[3, 2], [2, -1]])
b = np.array([8, 3])
x = np.linalg.solve(A, b) # 输出: [2. 1.] 即 x=2, y=1
np.allclose(A @ x, b) # 输出: True 验证:代回原方程成立
💡
A @ x == b的写法在浮点运算下别用==判断,用np.allclose(允许微小误差)。解方程前先np.linalg.det(A)看看行列式是否非 0——为 0 说明无唯一解(奇异矩阵)。
结语
这 13 个知识点串起来就是一条完整的 NumPy 主线:创建 → 属性 → 索引 → 运算 → 形状 → ufunc → 统计 → 广播 → 筛选 → 拼接 → IO → 随机 → 线代。
回到我们的成绩表:从 np.array 建表(第 1 节)→ 看 shape(第 2 节)→ 取某人某科(第 3 节)→ 加平时分(第 4 节)→ 算每科平均(第 7 节)→ 按行广播加成(第 8 节)→ 筛不及格(第 9 节)→ 拼接新同学(第 10 节)→ 存档(第 11 节)——这一整套就是最朴素的"成绩处理流水线",Excel 能做的,这 13 节全都能做。
每一章都有对应的独立文章可以深挖,尤其是 广播机制 和 花式索引 这两个难点,值得单独反复看。
📚 配套系列:13 章详细版
速通是主线,每章还有一篇独立的详细文章,想深挖哪章点哪章:
| 章节 | 内容 |
|---|---|
| 第 1 章 创建数组 | np.array、zeros、ones、arange、linspace |
| 第 2 章 数组属性 | shape、ndim、size、dtype |
| 第 3 章 索引与切片 | 基本索引、切片、花式索引 |
| 第 4 章 数组运算 | 逐元素运算、标量运算 |
| 第 5 章 形状操作 | reshape、flatten、ravel、转置 |
| 第 6 章 通用函数 | sqrt、exp、log 等 ufunc |
| 第 7 章 统计与聚合 | sum、mean、max、axis |
| 第 8 章 广播机制 | ⭐ 重点难点 |
| 第 9 章 布尔索引与筛选 | 条件筛选、掩码、where |
| 第 10 章 数组拼接与分割 | concatenate、vstack、hstack、split |
| 第 11 章 文件读写 | save、load、.npy / .npz |
| 第 12 章 随机数 | random、种子、常见分布 |
| 第 13 章 线性代数基础 | 矩阵乘法、inv、det、solve、eig |
💡 学习建议:光看懂了不算会,合上文章亲手敲一遍,报错的地方就是还没真懂的地方。