pin_drop当前位置:知识文库 ❯ 图文
NumPy随机数生成器教程 - 概率分布与随机采样
一、概述
NumPy的random模块提供了丰富的随机数生成功能,包括均匀分布、正态分布、泊松分布等各种概率分布的随机数生成,以及随机采样、随机排列等操作。这些功能在模拟实验、数据增强、模型初始化等场景中广泛使用。
从NumPy 1.17版本开始,推荐使用新的Generator API(np.random.default_rng()),它比旧的全局RandomState API更快、更灵活、更安全。新的API支持多种随机数生成算法(如PCG64),并且每个Generator实例独立,适合多线程环境。
二、语法与常用方法
代码示例
# 新版API(推荐)
rng = np.random.default_rng(seed)
rng.random(size)
rng.integers(low, high, size)
rng.normal(loc, scale, size)
rng.choice(a, size)
rng.shuffle(a)
# 旧版API
np.random.seed(seed)
np.random.rand(d0, d1)
np.random.randint(low, high, size)
np.random.randn(d0, d1)三、参数说明
Generator常用方法
常用概率分布
四、基本随机数生成
使用default_rng()创建随机数生成器后,可以生成各种类型的随机数。设置种子(seed)可以保证每次运行的结果一致,便于调试和复现。
代码示例
import numpy as np
# 创建随机数生成器(设置种子保证可复现)
rng = np.random.default_rng(42)
# [0,1)均匀分布
print(f"单个随机数: {rng.random():.6f}")
print(f"3个随机数: {rng.random(3)}")
print(f"2x3随机矩阵:\n{rng.random((2, 3))}")
# 整数随机数
print(f"\n[1,10)整数: {rng.integers(1, 10, size=5)}")
print(f"[0,100)整数: {rng.integers(100, size=(2, 4))}")输出结果:
代码示例
单个随机数: 0.773956
3个随机数: [0.43887844 0.85859792 0.69736803]
2x3随机矩阵:
[[0.09417735 0.97562235 0.7611397 ]
[0.78606431 0.12811363 0.45038594]]
[1,10)整数: [4 9 5 1 3]
[0,100)整数: [[34 56 29 56]
[19 77 34 52]]五、概率分布随机数
NumPy支持多种概率分布的随机数生成。正态分布在自然界和工程中最为常见;泊松分布用于描述单位时间内事件发生的次数;二项分布描述n次独立伯努利试验中成功次数;指数分布常用于建模等待时间。
代码示例
import numpy as np
rng = np.random.default_rng(42)
# 正态分布
normal = rng.normal(loc=0, scale=1, size=5)
print(f"正态分布(μ=0,σ=1): {np.round(normal, 4)}")
# 均匀分布
uniform = rng.uniform(low=10, high=20, size=5)
print(f"均匀分布[10,20): {np.round(uniform, 4)}")
# 泊松分布
poisson = rng.poisson(lam=5, size=10)
print(f"泊松分布(λ=5): {poisson}")
# 二项分布
binomial = rng.binomial(n=10, p=0.5, size=10)
print(f"二项分布(n=10,p=0.5): {binomial}")
# 指数分布
exponential = rng.exponential(scale=2, size=5)
print(f"指数分布(β=2): {np.round(exponential, 4)}")输出结果:
代码示例
正态分布(μ=0,σ=1): [ 0.3047 -1.0399 0.7509 0.9406 -1.4297]
均匀分布[10,20): [12.7683 19.4494 17.6144 10.276 12.3529]
泊松分布(λ=5): [ 5 7 5 4 5 4 5 5 10 3]
二项分布(n=10,p=0.5): [5 4 5 6 5 5 5 5 5 4]
指数分布(β=2): [1.5684 1.0605 0.4585 3.5589 0.8588]六、随机采样与打乱
choice()用于从给定总体中随机采样,支持放回/不放回和加权采样。shuffle()原地打乱数组,permutation()返回新数组不修改原数组。
代码示例
import numpy as np
rng = np.random.default_rng(42)
# 随机采样(不放回)
sample = rng.choice([10, 20, 30, 40, 50], size=3, replace=False)
print(f"不放回采样: {sample}")
# 随机采样(放回)
sample2 = rng.choice([10, 20, 30, 40, 50], size=5, replace=True)
print(f"放回采样: {sample2}")
# 带权重的采样
weights = [0.4, 0.3, 0.2, 0.1, 0.0]
sample3 = rng.choice([10, 20, 30, 40, 50], size=10, p=weights)
print(f"加权采样: {sample3}")
# 打乱数组
arr = np.arange(10)
rng.shuffle(arr)
print(f"打乱后: {arr}")
# 随机排列(不修改原数组)
arr2 = np.arange(10)
perm = rng.permutation(arr2)
print(f"原数组: {arr2}")
print(f"随机排列: {perm}")输出结果:
代码示例
不放回采样: [40 10 20]
放回采样: [40 40 50 10 10]
加权采样: [10 10 10 20 10 10 30 20 10 20]
打乱后: [8 1 5 0 7 2 9 4 3 6]
原数组: [0 1 2 3 4 5 6 7 8 9]
随机排列: [7 0 3 9 5 2 4 8 1 6]小贴士
加权采样时,权重数组p的所有元素必须非负且总和为1。shuffle()是原地操作,直接修改传入的数组;permutation()返回新数组,原数组不变。根据是否需要保留原始数据来选择使用哪个函数。
七、实际应用场景
-
场景1:机器学习中,使用正态分布随机数初始化神经网络权重,如Xavier初始化和He初始化
-
场景2:数据科学中,使用随机采样划分训练集和测试集,确保模型评估的可靠性
-
场景3:蒙特卡洛模拟中,使用各种分布的随机数进行概率估计和金融建模
八、注意事项
注意:推荐使用新版API(default_rng),旧版全局API在多线程环境下不安全,且算法较为陈旧。
注意:设置随机种子(seed)可以保证结果可复现,但不同版本NumPy的随机数序列可能不同,升级版本后注意验证。
注意:shuffle是原地操作,permutation返回新数组不修改原数组。根据是否需要保留原始数据选择使用。
九、新旧API对比
十、练习题
练习1
使用default_rng创建随机数生成器,生成1000个正态分布随机数,计算均值和标准差,验证是否接近理论值
练习2
编写程序,使用choice()从1到100中随机抽取10个不重复的数字
练习3
编写程序,模拟掷骰子10000次,统计每个点数出现的频率,验证是否接近1/6
常见问题
为什么推荐使用default_rng而不是旧的np.random?
default_rng使用PCG64算法,速度比MT19937更快,统计特性更好,并且每个生成器实例独立,适合多线程环境。旧版API使用全局状态,在并发场景下容易产生竞态条件。
设置随机种子后为什么能保证结果可复现?
伪随机数生成器通过确定性的数学算法产生数字序列,相同的种子会产生完全相同的序列。这在调试和实验复现中非常有用。
什么是伪随机数?和真随机数有什么区别?
伪随机数由确定性算法生成,给定相同种子会得到相同序列。真随机数需要物理随机源(如放射性衰变)。计算机中使用的都是伪随机数,但现代算法的统计特性已经非常接近真随机。
choice的加权采样中p参数有什么要求?
p参数是一个概率分布数组,所有元素必须非负且总和为1。如果总和不为1,会抛出ValueError。权重越大,对应元素被选中的概率越高。
本文涉及AI创作
内容由AI创作,请仔细甄别