本系列是《NumPy 速通》的配套章节。
生成随机数——初始化参数、模拟数据、打乱顺序都靠它。本章核心:新接口 default_rng、种子可复现、常用分布、以及"随机打乱 vs 抽样"。
推荐用法:default_rng(NumPy 1.17+)
import numpy as np
rng = np.random.default_rng(42) # 传入种子,结果可复现
default_rng 是 NumPy 新推荐的接口(1.17+),比老的 np.random.rand() / np.random.seed() 更好:
| 老接口(不推荐) | 新接口(推荐) |
|---|---|
np.random.seed(42) 全局设置 |
rng = np.random.default_rng(42) 独立对象 |
np.random.rand(5) |
rng.random(5) |
np.random.randint(0, 10) |
rng.integers(0, 10) |
np.random.normal(0, 1) |
rng.normal(0, 1) |
💡 老接口是全局状态(影响整个程序);新接口每个
rng是独立的随机源——多线程、多模块不互相干扰,是现代推荐写法。
常用随机函数
rng = np.random.default_rng(42)
rng.random(5) # 均匀分布 [0,1),一维 5 个
rng.random((2, 3)) # 均匀分布,2 行 3 列
rng.normal(0, 1, 10) # 正态分布(均值 0,标准差 1)
rng.integers(0, 10, 5) # 0~9 的随机整数,5 个
rng.permutation(10) # 0~9 的随机排列
rng.uniform(0, 10, 5) # 均匀分布 [0,10)
rng.choice([1,2,3,4,5], size=3) # 从列表随机抽 3 个
rng.choice([1,2,3,4,5], size=3, replace=False) # 不重复抽样
⭐ 种子(seed)的作用:可复现性
rng1 = np.random.default_rng(42)
rng2 = np.random.default_rng(42)
rng1.random(3) # [0.37454012 0.95071431 0.73199394]
rng2.random(3) # [0.37454012 0.95071431 0.73199394] 一样!
传同样的种子 → 生成同样的序列。这保证了实验可复现:
- 机器学习训练前固定种子 → 每次跑结果一致,方便调参与对比
- 论文/实验要求可复现 → 种子是标配
⚠️ 灵魂警告:
- 不传种子 → 每次运行结果都不同(真正的"随机"),无法复现 bug
- 但不要给
default_rng传0——0是合法种子没错,但很容易和"没传"混淆。习惯用 42 等非零数- 别每次调用都新建 rng(
np.random.default_rng()每个都是独立随机源,等价于重开一个世界)
打乱数组:shuffle vs permutation
arr = np.arange(10)
rng.shuffle(arr) # 原地打乱(修改 arr 本身)
rng.permutation(arr) # 返回打乱后的副本(不改原数组)
rng.permutation(10) # 直接生成 0~9 的随机排列
区别:
shuffle:原地修改,返回 None——用完原数组就变了permutation:返回新数组,原数组不动
💡 数据洗牌实战:机器学习训练前要同时打乱特征 X 和标签 y,且顺序要一致:
idx = rng.permutation(len(X)) # 打乱索引 X = X[idx] y = y[idx]用"打乱索引"的方式,X 和 y 保持一一对应。
常见分布
rng.normal(0, 1, 1000) # 正态分布(均值 0,标准差 1)→ 最常用
rng.uniform(0, 10, 100) # 均匀分布
rng.poisson(5, 100) # 泊松分布(均值 λ=5)→ 计数数据
rng.binomial(10, 0.5, 100) # 二项分布(n 次实验,成功概率 p)
rng.exponential(1.0, 100) # 指数分布 → 等待时间
rng.gamma(2.0, 2.0, 100) # Gamma 分布
rng.lognormal(0, 1, 100) # 对数正态 → 收入、股价等右偏数据
💡 具体用哪个分布,取决于你的数据模型:
- 身高、误差、成绩 → 正态
normal- 抛硬币、通过/失败 → 二项
binomial- 每分钟到达人数、故障次数 → 泊松
poisson- 等车时间、服务时间 → 指数
exponential
实战:模拟掷骰子 / 抽样检验
# 掷 6 面骰子 10000 次,统计各面出现次数
rolls = rng.integers(1, 7, 10_000)
counts = np.bincount(rolls)[1:] # 每面出现次数
print(counts) # 大致均匀分布
# 从 100 人中随机抽 10 人(不重复)
sample = rng.choice(100, size=10, replace=False)
小结
- 一律用
np.random.default_rng(种子)创建独立随机源 - 固定种子 → 可复现(机器学习标配)
shuffle原地改;permutation返回副本- 分布按数据模型选:normal / binomial / poisson / exponential…
- 抽样用
rng.choice,支持replace=False不重复
下一章(最后一章):线性代数基础。
上一篇:第 11 章 文件读写 | 下一篇:第 13 章 线性代数基础
上一篇:第 11 章 文件读写 | 下一篇:第 13 章 线性代数基础