本系列是《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)

小结

  1. 一律用 np.random.default_rng(种子) 创建独立随机源
  2. 固定种子 → 可复现(机器学习标配)
  3. shuffle 原地改;permutation 返回副本
  4. 分布按数据模型选:normal / binomial / poisson / exponential…
  5. 抽样用 rng.choice,支持 replace=False 不重复

下一章(最后一章):线性代数基础。


上一篇:第 11 章 文件读写 | 下一篇:第 13 章 线性代数基础


上一篇:第 11 章 文件读写 | 下一篇:第 13 章 线性代数基础