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常用方法

方法 参数 说明
random(size) size: 形状 [0,1)均匀分布随机数
integers(low, high, size) low/high: 范围, size: 形状 [low,high)整数随机数
normal(loc, scale, size) loc: 均值, scale: 标准差 正态分布随机数
uniform(low, high, size) low/high: 范围 均匀分布随机数
choice(a, size, replace) a: 总体, replace: 是否放回 随机采样
shuffle(a) a: 数组 原地随机打乱
permutation(a) a: 数组/整数 返回随机排列
bytes(length) length: 字节数 随机字节

常用概率分布

方法 说明
normal() 正态(高斯)分布
uniform() 均匀分布
binomial() 二项分布
poisson() 泊松分布
exponential() 指数分布
beta() Beta分布
gamma() Gamma分布
chi_square() 卡方分布

四、基本随机数生成

使用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对比

特性 default_rng (新) RandomState (旧)
生成器 独立实例 全局状态
线程安全 安全 不安全
性能 更快 较慢
算法 PCG64 MT19937
整数范围 [low, high) [low, high)
推荐程度 推荐 不推荐

十、练习题

练习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。权重越大,对应元素被选中的概率越高。

标签: NumPy 随机数 概率分布 随机采样 正态分布 default_rng

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: NumPy线性代数完整教程 - 矩阵运算与SVD分解 下一篇: NumPy文件读写完整指南 - npy/npz/CSV格式

poll相关推荐