np.random.default_rng 是新版推荐写法,老的 np.random.rand 还能用但不推荐。 种子固定,结果就固定。报数必须交代种子,否则别人复现不了。 normal 的两个参数是均值和标准差,不是均值和方差。
造测试数据、随机分组、随机抽样都靠随机数。这一篇把「可复现」这件事讲透。 不做随机模拟也值得看:种子是数据分析的诚信底线。
一、新版写法:default_rng
rng = np.random.default_rng() 造一个随机数生成器。
然后 rng.integers(0, 10, 5) 取五个 0 到 9 的整数。
老的 np.random.rand 还能用,但官方建议统一换到 default_rng。
两者最大的区别是:生成器是一个对象,可以独立持有状态,不会互相干扰。
二、种子:可复现
np.random.default_rng(42).integers(0, 100, 5) 连跑两次,结果一模一样。
种子 42 定了,整条随机序列就定了。
报数必须交代种子。不给种子,别人复现不了你的结果,那个数就是孤证。
这不是洁癖。做随机模拟时,改一个参数结果就变,没有种子根本分不清是参数起作用还是随机波动。
三、三种常用分布
| 要什么 | 怎么写 | 范围 |
|---|---|---|
| 整数 | integers(低, 高, 个数) | 右端不含 |
| 0 到 1 小数 | random(个数) | 左闭右开 |
| 正态分布 | normal(均值, 标准差, 个数) | 无上下界 |
integers 的右端不包含,和 arange 一样——写 integers(0, 10) 给的是 0 到 9。
normal 的两个参数是均值和标准差,不是均值和方差。这一点常记错。
标准差 1 意味着约 68% 的数落在 -1 到 1 之间。
四、打乱与抽样
rng.permutation(A) 洗牌,返回新数组,不改原数组。
rng.choice(10, 3, replace=False) 从 10 个里抽 3 个不重复的。
replace=False 是不放回。忘了写默认有放回,可能抽到重复的。
随机分组就是先用 permutation 洗牌,再按顺序切两半。
五、随机数的四个用处
| 用途 | 怎么写 |
|---|---|
| 造测试数据 | integers 或 normal |
| 随机分组(A/B 测试) | permutation 洗牌再切 |
| 随机抽样 | choice(replace=False) |
| 初始化权重 | normal 小标准差 |
造测试数据时一定要给种子,不然每次跑出来都不一样,debug 就没法比。 没有种子的随机测试,等于每次都换一份数据在测。
六、动手 Demo:随机数组与随机种子
先看同一个生成器连取两次不一样,再看固定种子两次完全一样。 最后演示三种分布、洗牌和抽样。
import numpy as np
R = np.random.default_rng(20261102)
print("第一次 %s" % R.integers(0, 10, 5))
print("第二次 %s" % R.integers(0, 10, 5))
print("种子 42:%s" % np.random.default_rng(42).integers(0, 100, 5))
print("再来一次:%s" % np.random.default_rng(42).integers(0, 100, 5))
R = np.random.default_rng(7)
print("整数 %s" % R.integers(0, 100, 5))
print("小数 %s" % np.round(R.random(5), 3))
print("正态 %s" % np.round(R.normal(0, 1, 5), 3))
R = np.random.default_rng(3)
A = np.arange(10)
print("原数组 %s" % A)
print("洗牌后 %s" % R.permutation(A))
print("抽样 %s" % R.choice(10, 3, replace=False))
实跑输出:
--------------------------------------------------------------------
随机数组与随机种子
--------------------------------------------------------------------
① 新版写法:default_rng
--------------------------------------------------------------------
第一次:[7 6 2 4 7]
第二次:[8 0 8 0 3]
同一个生成器连着取,每次都不一样——这是随机的本意。
! np.random.default_rng 是新版推荐写法。老的 np.random.rand 还能用,但官方建议换。
② 种子:可复现
--------------------------------------------------------------------
种子 42 造两次:[ 8 77 65 43 43]
再来一次: [ 8 77 65 43 43]
两次完全一样。种子固定,结果就固定。
! 报数必须交代种子。不给种子,别人复现不了你的结果,那个数就是孤证。
③ 三种常用分布
--------------------------------------------------------------------
整数:integers(0, 100, 5) → [94 62 68 89 57]
小数:random(5) → [0.225 0.3 0.874 0.005 0.821]
正态:normal(均值 0, 标准差 1, 5 个) → [-0.492 -0.62 0.49 0.357 0.105]
integers 的右端不包含,和 arange 一样;random 给 0 到 1 之间的小数。
! normal 的两个参数是均值和标准差,不是均值和方差。这一点常记错。
④ 打乱与抽样
--------------------------------------------------------------------
原数组:[0 1 2 3 4 5 6 7 8 9]
洗牌后:[9 6 0 2 1 4 7 5 3 8]
原数组还是:[0 1 2 3 4 5 6 7 8 9]——permutation 返回新数组,不改原数组。
从 10 个里抽 3 个不重复:[5 4 3]
! 抽样的 replace=False 是不放回。忘了写默认是有放回,可能抽到重复的。
⑤ 随机数能干什么
--------------------------------------------------------------------
| 用途 | 怎么写 |
|---|---|
| 造测试数据 | integers 或 normal |
| 随机分组 | permutation 洗牌再切 |
| 随机抽样 | choice(replace=False) |
| 初始化权重 | normal 小标准差 |
造测试数据时一定要给种子,不然每次跑出来都不一样,debug 就没法比。
default_rng(42) 每次都新建一个生成器,所以两次结果一样;R 是同一个生成器,所以两次不一样。
「同一个生成器连取」和「新建两个同种子生成器」结果完全不同。这是最容易混的一点。
30 秒实验
- 把种子 42 改成 43,看五个数变成什么。
- 把 choice 的 replace=False 去掉,连跑几次看有没有重复。
- 想一想:为什么 A/B 测试要随机分组?不随机会怎样?
常见误区
- 不设种子:每次跑结果不同,出了问题无法复现。
- 以为 normal 第二个参数是方差:它是标准差,方差要开根号。
- 抽样忘了 replace=False:抽到重复的,样本量不够。
- 以为 permutation 改原数组:它返回新数组,原数组不动。
自测三问(点开对答案)
1. 为什么报数必须交代种子? —— 没有种子,同一个随机过程每次结果不同,别人无法复现,结论也就无法验证。 2. normal(0, 1) 的两个参数是什么? —— 均值 0、标准差 1。不是均值 0、方差 1。 3. 随机分组怎么做? —— 先用 permutation 把行号洗牌,再按顺序切段,比如前一半是 A 组。造数组的方式都讲完了。下一篇讲一个隐蔽的坑:asarray 和 array 差在「复不复制」。
- ☐ (本篇完,下一篇 6.5 从已有数组创建)