当前位置: 首页 > news >正文

NumPy 2.x 完全指南【三十八】伪随机数生成器

文章目录

  • 1. 概述
  • 2. 种子(Seed)
  • 3. Generator 类
    • 3.1 BitGenerator
    • 3.2 创建子生成器
    • 3.3 生成简单随机数
    • 3.4 生成随机排列

1. 概述

numpy.random 模块是 NumPy 库中用于生成随机数的核心模块,它实现了伪随机数生成器(Pseudorandom Number Generators, 简称 PRNGsRNGs)。这些生成器能够从各种概率分布中抽取样本,是科学计算、数据分析和机器学习中不可或缺的工具。

一般使用 random.default_rng() 创建一个 Generator 实例,然后调用生成器的各种方法从不同分布中获取样本。

示例 1 ,生成一个在 [0, 1) 范围内均匀分布的随机浮点数:

# 创建生成器实例
rng = np.random.default_rng()
# 生成随机数
res=rng.random()
print(res) # 输出可能类似:0.5737686083064519

注意事项:伪随机数生成器设计用于统计建模和模拟,它们不适用于安全或加密目的。

2. 种子(Seed)

伪随机数生成器的本质是确定性。它从一个称为种子的初始值开始,通过预先设计好的数学算法进行计算,生成看似随机的数字序列,只要种子相同,算法相同,产生的序列就完全一致。

示例 1,设置相同种子时,不同的伪随机数实例,输出结果完全一样:

rng = np.random.default_rng(1)
res=rng.random()
print(res) # 0.5118216247002567rng = np.random.default_rng(1)
res=rng.random()
print(res) # 0.5118216247002567

default_rng() 有且仅有一个 seed 参数用于设置种子,可选值有:

  • None:从操作系统获取随机熵源,产生不可预测的随机序列。
  • int:使用特定整数值初始化种子,相同的整数种子会产生相同的随机数序列。
  • array_like[ints]:使用整数数组初始化种子,提供更多的熵源,可能增强随机数生成的初始状态多样性。
  • SeedSequence:使用一个 SeedSequence 实例来初始化,支持生成独立且可重复的并行随机数流。
  • BitGenerator:直接传递一个 BitGenerator (底层随机比特生成器),它将被 Generator 包装。
  • Generator:直接传递一个 Generator 实例,函数会将其原样返回。
  • RandomState:传递一个旧的 RandomState 实例,它将被转换为新的 Generator 实例。

在设置 seed 参数时,为了确保统计独立性和可重现性,确保你的种子与他人的不同,最好使用大且独一无二的正整数作为种子。获取此类种子数字的一个简便方法是使用 secrets.randbits 获取一个任意的 128 位整数。

示例 2 ,生成并使用一个 128 位的随机种子:

import secrets
seed = secrets.randbits(128)  # 输出可能类似:122807528840384100672342137672332424406
rng1 = np.random.default_rng(seed)
rng1.random()  # 输出:0.5363922081269535

3. Generator 类

random.default_rng() 会创建一个 Generator 实例,Generator 部分类定义如下:

class Generator:def __init__(self, bit_generator: BitGenerator) -> None: ...def __repr__(self) -> str: ...def __str__(self) -> str: ...def __getstate__(self) -> None: ...def __setstate__(self, state: dict[str, Any] | None) -> None: ...def __reduce__(self) -> tuple[Callable[[BitGenerator], Generator],tuple[BitGenerator],None]: ...@propertydef bit_generator(self) -> BitGenerator: ...

3.1 BitGenerator

Generator 类是面向用户的用户接口,内部的 BitGenerator 才是真正的底层引擎,用于生成高质量的原始随机比特序列,并提供给上层的 Generator 来转换为各种分布的随机数。

NumPy 实现了多种 BitGenerator 类,采用了不同的随机数生成算法:

  • PCG64:默认算法。
  • MT19937:经典的梅森旋转算法。
  • Philox:计数器模式的密码学启发算法。
  • SFC64Small Fast Chaotic 算法。

直接使用 np.random.default_rng() 即可,它会使用默认且推荐的 PCG64 算法:

# 创建一个主生成器
main_rng = np.random.default_rng(seed=42)# 访问 bit_generator 属性
bit_gen = main_rng.bit_generator
print("底层 BitGenerator 类型:", type(bit_gen))  # 例如: <class 'numpy.random._pcg64.PCG64'>

更换底层随机数算法时,无需改动上层 Generator 的接口和功能,用户只需在创建 Generator 时指定不同的 BitGenerator 即可:

from numpy.random import Generator, PCG64, MT19937, Philox# 用于旧式 MT19937 算法
rng = np.random.default_rng(MT19937(seed=42))# 生成随机数
res = rng.random()
print(res)  # 输出可能类似:0.5419938930062744

3.2 创建子生成器

spawn(n_children) 方法可以创建多个独立的、新的子生成器,常用于并行计算。

示例:

# 创建一个主生成器
main_rng = np.random.default_rng(seed=42)
# 使用 spawn 方法创建独立的子生成器
num_children = 3
child_generators = main_rng.spawn(num_children)# 这些子生成器可以用于并行任务,确保每个任务都有独立的随机源
for i, child_rng in enumerate(child_generators):print(f"子生成器 {i} 的随机数: {child_rng.random(3)}")

3.3 生成简单随机数

函数名称及常用参数主要功能重要参数说明
integers(low[, high, size, dtype, endpoint])生成随机整数- low: 下限(包含)。
- high: 上限(默认不包含,endpoint=True 时包含)。
- size: 输出形状。
- dtype: 数据类型。
- endpoint: 若为 True,则区间包含 high
random([size, dtype, out])**生成 [0.0, 1.0) 范围内的随机浮点数- size: 输出形状。
choice(a[, size, replace, p, axis, shuffle])从给定数组 a随机抽取元素。- a: 输入数组或整数。
- size: 输出形状。
- replace: 是否允许重复抽取(有放回抽样)。
- p: 各元素被抽中的概率。
bytes(length)生成随机字节- length: 生成的字节数。

np.random.Generator.integers 是生成随机整数的首选方法。其核心参数是 lowhigh,用于指定随机整数的范围。默认情况下,这个区间是左闭右开 [low, high)。如果需要包含 high,可以设置 endpoint=True

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器# 生成 1 个 [0, 5) 之间的随机整数
print(rng.integers(5))  # 输出:例如 3# 生成 3 个 [0, 5) 之间的随机整数
print(rng.integers(5, size=3))  # 输出:例如 array([3, 4, 0])# 生成 3 个 [2, 8) 之间的随机整数
print(rng.integers(2, 8, size=3))  # 输出:例如 array([7, 2, 6])# 生成 2x3 的数组,元素在 [10, 20) 之间
print(rng.integers(10, 20, size=(2, 3)))
# 输出:例如 array([[18, 15, 11],
#                  [13, 19, 10]])# 生成 2 个 [1, 4] 之间的随机整数 (使用 endpoint=True 使区间包含 high)
print(rng.integers(1, 4, endpoint=True, size=2))  # 输出:例如 array([1, 4])

np.random.Generator.random 用于生成半开区间 [0.0, 1.0) 内的随机浮点数。可以通过 size 参数指定输出数组的形状。

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器# 生成 1 个随机浮点数
print(rng.random())  # 输出:例如 0.77395605# 生成 5 个随机浮点数的一维数组
print(rng.random(size=5))
# 输出:例如 array([0.43887844, 0.85859792, 0.69736803, 0.09417735, 0.97562235])# 生成 2x3 的随机浮点数数组
print(rng.random(size=(2, 3)))
# 输出:例如 array([[0.7611397 , 0.78606431, 0.12811363],
#                  [0.45038594, 0.37079802, 0.92676499]])

np.random.Generator.choice 可以从给定的数组或整数序列中随机抽取元素。参数 a 可以是一个一维数组,也可以是一个整数(此时相当于从 np.arange(a) 中抽取)。replace 参数控制是否允许重复抽取(默认为 True,即有放回抽样),p 参数可以指定每个元素被抽中的概率。

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器
data = np.array([10, 20, 30, 40, 50])# 从 data 中随机抽取 1 个元素
print(rng.choice(data))  # 输出:例如 30# 从 data 中随机抽取 3 个元素(有放回)
print(rng.choice(data, size=3))  # 输出:例如 array([10, 30, 20])# 从 data 中随机抽取 3 个元素(无放回,replace=False)
print(rng.choice(data, size=3, replace=False))  # 输出:例如 array([40, 10, 50])# 从 0 到 4 (即 np.arange(5)) 中随机抽取 3 个数
print(rng.choice(5, size=3))  # 输出:例如 array([0, 3, 3])# 指定抽取概率:p=[0.1, 0.1, 0.2, 0.3, 0.3],分别对应 data 中的每个元素
print(rng.choice(data, size=3, p=[0.1, 0.1, 0.2, 0.3, 0.3]))
# 输出:例如 array([50, 40, 40]) (40 和 50 被抽中的概率更高)

np.random.Generator.bytes 用于生成随机字节字符串。它接受一个参数 length,指定要生成的字节数。这在需要生成加密密钥、随机令牌或任何需要原始随机字节的场景中非常有用。

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器# 生成 5 个随机字节
random_bytes = rng.bytes(5)
print(random_bytes)  # 输出:例如 b'\x1a\x2b\x3c\x4d\x5e' (显示为十六进制形式)# 生成 10 个随机字节
print(rng.bytes(10))  # 输出:例如 b'\x6f\x7a\x8b\x9c\xad\xbe\xcf\xd0\xe1\xf2'

3.4 生成随机排列

方法是否修改原数组返回值轴处理方式
shuffle(x) (原地)None将输入视作一维序列,沿给定轴整体打乱。
permutation(x)新数组(副本)将输入视作一维序列,沿给定轴整体打乱。
permuted(x)可选打乱后的数组沿指定轴独立地对每个切片进行重排,非整体打乱。

shuffle 会直接修改原始数组(原地操作),不返回任何值(返回 None)。它默认将数组视作一维序列进行打乱。对于多维数组,axis 参数指定哪个轴被当作这个“一维序列”来处理。

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器# 打乱列表 (非NumPy数组也行,会就地修改)
my_list = [1, 2, 3, 4, 5]
rng.shuffle(my_list)
print("打乱后的列表:", my_list)  # 输出: 例如 [2, 5, 1, 4, 3]# 打乱一维数组
arr_1d = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr_1d)
print("打乱后的一维数组:", arr_1d)  # 输出: 例如 [2, 5, 1, 4, 3]# 打乱二维数组 - 默认沿 axis=0(行)整体打乱
arr_2d = np.arange(9).reshape(3, 3)
print("原始二维数组:")
print(arr_2d)
# 输出:
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]rng.shuffle(arr_2d)  # 整体打乱行顺序
print("整体打乱行后:")
print(arr_2d)
# 输出(示例):
# [[3 4 5]   # 原第二行
#  [0 1 2]   # 原第一行
#  [6 7 8]]  # 原第三行
# 每行内部元素顺序不变

permutation 不修改原始数组,而是返回一个打乱后的新数组副本。和 shuffle 一样,它默认也将输入视作一维序列进行处理,axis 参数的含义相同。

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器# 输入整数 n:返回 0 到 n-1 的随机排列
permuted_range = rng.permutation(5)
print("0到4的随机排列:", permuted_range)  # 输出: 例如 [2 0 3 1 4]# 输入一维数组:返回打乱后的新数组,原数组不变
arr_1d = np.array([1, 2, 3, 4, 5])
permuted_1d = rng.permutation(arr_1d)
print("原一维数组:", arr_1d)         # 输出: [1 2 3 4 5] (不变)
print("打乱后的新数组:", permuted_1d)  # 输出: 例如 [2 5 1 4 3]# 输入二维数组:沿 axis=0(行)整体打乱,返回新数组
arr_2d = np.arange(9).reshape(3, 3)
print("原始二维数组:")
print(arr_2d)
# 输出:
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]permuted_2d = rng.permutation(arr_2d) # 整体打乱行顺序
print("整体打乱行后的新数组:")
print(permuted_2d)
# 输出(示例):
# [[3 4 5]   # 原第二行
#  [0 1 2]   # 原第一行
#  [6 7 8]]  # 原第三行
# 原数组不变,每行内部元素顺序不变

permuted 在轴处理上与前两者不同,它是沿指定轴独立地对每个切片进行重排,而不是将输入视作一个整体序列。它可以通过 out 参数选择是返回新数组还是原地修改

示例:

rng = np.random.default_rng(seed=42)  # 创建随机数生成器arr_2d = np.arange(9).reshape(3, 3)
print("原始二维数组:")
print(arr_2d)
# 输出:
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]# 沿 axis=1 (列) 独立打乱:每行内部元素独立重排
permuted_indep = rng.permuted(arr_2d, axis=1)
print("每行内部独立打乱后的新数组:")
print(permuted_indep)
# 输出(示例):
# [[1 0 2]  # 第一行内部打乱
#  [5 3 4]  # 第二行内部打乱
#  [8 6 7]] # 第三行内部打乱
# 原数组不变# 使用 out 参数进行原地操作
rng.permuted(arr_2d, axis=1, out=arr_2d) # 将结果写回原数组
print("原地每行独立打乱后的数组:")
print(arr_2d)
# 输出(示例):
# [[1 0 2]
#  [5 3 4]
#  [8 6 7]]

文章转载自:

http://tSndj8UG.spLcc.cn
http://kHreTk4V.spLcc.cn
http://PrdXpyXk.spLcc.cn
http://lS0FQcev.spLcc.cn
http://iOytYNt5.spLcc.cn
http://9NCI4EYv.spLcc.cn
http://4JXHITWd.spLcc.cn
http://oXLCrXsa.spLcc.cn
http://pfcgmjCg.spLcc.cn
http://W2jIyVNk.spLcc.cn
http://VGZNvrQb.spLcc.cn
http://6AKkrtWo.spLcc.cn
http://LAx5pTZo.spLcc.cn
http://SAzlWPmQ.spLcc.cn
http://4Mf3k23n.spLcc.cn
http://j3ZvlWR6.spLcc.cn
http://gk8pDoVa.spLcc.cn
http://P5z9nSAi.spLcc.cn
http://t6k6eI94.spLcc.cn
http://y0XZJwpO.spLcc.cn
http://2YGE5vTG.spLcc.cn
http://moOX23b7.spLcc.cn
http://xxh7T15C.spLcc.cn
http://mySnSAOa.spLcc.cn
http://70mBuqLs.spLcc.cn
http://pYMmDpCK.spLcc.cn
http://tjb0ZteJ.spLcc.cn
http://k7zEoddq.spLcc.cn
http://liXVpL16.spLcc.cn
http://QIlA16mS.spLcc.cn
http://www.dtcms.com/a/379779.html

相关文章:

  • GitHub 热榜项目 - 日榜(2025-09-12)
  • O3.3 opencv指纹识别
  • 在线会议系统是一个基于Vue3 + Spring Boot的现代化在线会议管理平台,集成了视频会议、实时聊天、AI智能助手等多项先进技术。
  • 每日一算:打家劫舍
  • MemGPT: Towards LLMs as Operating Systems
  • MySQL与PostgreSQL核心区别对比
  • Redis基础命令速查:从连接到数据操作,新手也能上手
  • 信息安全工程师考点-网络安全法律与标准
  • 阿里云OSS vs 腾讯云COS vs AWS S3:对象存储价格与性能深度对比
  • vim复制本地到linux服务器上,换行缩进过大,不对的问题
  • 【贪心算法】day9
  • HarmonyOS 5分布式数据管理初探:实现跨设备数据同步
  • 【Unity UGUI 交互组件——InputFild(TMP版本)(11)】
  • 基于QVTKOpenGLNativeWidget的三维点云可视化实现
  • Qwen3 中注意力机制实现
  • 基于librdkafa C++客户端生产者发送数据失败问题处理#2
  • Maya绑定:渲染编辑器Hypershade简单使用,给小球添加材质纹理
  • 前端基础 —— A / HTML
  • 线性代数 | 行列式与矩阵区别
  • Redis 核心数据结构:String 类型深度解析与 C++ 实战
  • 【Linux】面试常考!Linux 进程核心考点:写时拷贝优化原理 + 进程等待实战,一篇理清进程一生
  • 根据当前门店经纬度,求出1km内的门店
  • java类冲突
  • 线上的Python服务如何部署?
  • ​​Cinema 4D 2026 核心亮点:AI智能驱动 + 无缝实时渲染​
  • 【Pywinauto库】10.7 pywinauto.controls.uia_controls控件
  • Next.js 字体优化:使用 `next/font` 告别布局偏移和性能瓶颈
  • 腾讯滑块---Js逆向酷狗音乐登入
  • 机器学习算法概述
  • zzz‘sJavaweb知识点总结