codeye
2022/09/22阅读:21主题:默认主题
PYQT6
该模块为各种分布实现伪随机数生成器。random — 生成伪随机数 — Python 3.10.5 文档
对于整数,可以从范围中统一选择。对于序列,可以统一选择随机元素,使用函数生成就地列表的随机排列,以及不替换的随机采样函数。
在实线上,有一些函数可以计算均匀分布、正态分布(高斯分布)、对数正态分布、负指数分布、伽马分布和 beta 分布。为了生成角度分布,冯·米塞斯分布可用。
几乎所有的模块函数都依赖于基本函数 random(),它在半开范围 [0.0, 1.0] 中均匀生成随机浮点数。Python使用Mersenne Twister作为核心生成器。它生成 53 位精度浮点数,周期为 2**19937-1。C 中的基础实现既快速又是线程安全的。Mersenne Twister是现存测试最广泛的随机数生成器之一。但是,由于完全确定性,它并不适合所有目的,并且完全不适合加密目的。
此模块提供的函数实际上是随机的隐藏实例的绑定方法。随机类。您可以实例化自己的 Random 实例,以获取不共享状态的生成器。
如果你想使用你自己设计的不同基本生成器,也可以对类 Random 进行子类化:在这种情况下,重写 、 、 和方法。或者,一个新的生成器可以提供一种方法 - 这允许randrange()在任意大的范围内产生选择。random()seed()getstate()setstate()getrandbits()
随机模块还提供了 SystemRandom 类,该类使用系统函数 os.urandom() 从操作系统提供的源生成随机数。
警告 此模块的伪随机生成器不应用于安全目的。有关安全性或加密用途,请参阅机密模块。 另见M. Matsumoto和T. Nishimura,“Mersenne Twister:A 623维等分布均匀伪随机数生成器”,ACM Transactions on Modeling and Computer Simulation Vol. 8,No. 1,1998年1月3-30日。 与携带互补乘法配方,用于具有长周期和相对简单的更新操作的兼容替代随机数生成器。
random.seed() 初始化随机数生成器。
如果省略 或 ,则使用当前系统时间。如果随机性源由操作系统提供,则使用它们而不是系统时间(有关可用性的详细信息,请参阅 os.urandom() 函数)。None
如果 a 是 int,则直接使用它。
使用版本 2(默认值),str、字节或字节数组对象将转换为 int,并使用其所有位。
对于版本1(提供用于从旧版本的Python中复制随机序列),str和字节的算法生成更窄的种子范围。
版本3.2中的更改: 移至版本 2 方案,该方案使用字符串种子中的所有位。
自版本 3.9 起已弃用: 将来,种子必须是以下类型之一:NoneType、int、float、str、bytes 或 bytearray。
random.getstate() 返回捕获生成器当前内部状态的对象。此对象可以传递给 setstate() 以恢复状态。
random.setstate() state 应该是从之前对 getstate() 的调用中获取的,setstate() 将生成器的内部状态恢复到调用 getstate() 时的状态。
字节函数 random.randbytes(n) 生成 n 个随机字节。
此方法不应用于生成安全令牌。请改用 secrets.token_bytes()。
版本 3.9 中的新功能。
整数的函数 random.randrange(停) random.randrange(启动、停止、步幅]) 返回从 中随机选择的元素。这等效于 ,但实际上并不构建范围对象。range(start, stop, step)choice(range(start, stop, step))
位置参数模式与 range() 的模式匹配。不应使用关键字参数,因为该函数可能会以意外的方式使用它们。
在3.2版本中更改:randrange()在生成均匀分布的值方面更加复杂。以前,它使用的样式可能会产生略微不均匀的分布。int(random()*n)
自版本 3.10 起已弃用: 不推荐将非整数类型自动转换为等效整数。当前无损转换为 .将来,这将引发一个 TypeError。randrange(10.0)randrange(10)
自版本 3.10 起已弃用: 为非整数值(如 或)引发的异常将从 ValueError 更改为 TypeError。randrange(10.5)randrange('10')
random.randint(a, b) 返回一个随机整数 N,使得 .的别名。a <= N <= brandrange(a, b+1)
random.getrandbits(k) 返回一个具有 k 个随机位的非负 Python 整数。此方法随 MersenneTwister 生成器一起提供,其他一些生成器也可能将其作为 API 的可选部分提供。如果可用,getrandbits() 使 randrange() 能够处理任意大的范围。
版本3.9中更改: 此方法现在接受 k 的零。
序列函数 random.choice(seq) 从非空序列 seq 返回一个随机元素。如果 seq 为空,则引发 IndexError。
random.choices(总体, 权重=无, *, cum_weights=无, k=1) 返回从填充中选择的 k 大小的元素列表并进行替换。如果填充为空,则引发 IndexError。
如果指定了权重序列,则会根据相对权重进行选择。或者,如果给出了cum_weights序列,则根据累积权重进行选择(可能使用itertools.accumulate()计算)。例如,相对权重等效于 累积权重 。在内部,在进行选择之前,相对权重将转换为累积权重,因此提供累积权重可以节省工作。[10, 5, 30, 5][10, 15, 45, 50]
如果未指定权重或cum_weights,则以相等的概率进行选择。如果提供了权重序列,则该序列的长度必须与总体序列的长度相同。它是一个类型错误,用于同时指定权重和cum_weights。
权重或cum_weights可以使用与 random() 返回的浮点值(包括整数、浮点数和分数,但不包括小数)互操作的任何数值类型。权重被假定为非负且有限。如果所有权重均为零,则会引发值错误。
对于给定的种子,具有相等权重的 choices() 函数通常产生与重复调用 choice() 不同的序列。choices() 使用的算法使用浮点算术来实现内部一致性和速度。choice() 使用的算法默认为整数算术,并重复选择,以避免舍入误差产生的小偏差。
版本 3.6 中的新功能。
版本3.9中更改: 如果所有权重都为零,则引发值错误。
random.shuffle(x) 将序列 x 随机排列到位。
可选参数 random 是一个 0 参数函数,返回 [0.0, 1.0] 中的随机浮点数;默认情况下,这是函数 random()。)。
要对不可变序列进行随机排序并返回新的随机排列列表,请改用。sample(x, k=len(x))
注意,即使对于小的,x的排列总数也会很快大于大多数随机数生成器的周期。这意味着长序列的大多数排列永远无法生成。例如,长度为 2080 的序列是 Mersenne Twister 随机数生成器期间内可以拟合的最大序列。len(x)
自版本 3.9 起已弃用,将在版本 3.11 中删除: 可选参数随机。
random.sample(人口,k,*,计数=无) 返回从总体序列或集合中选择的唯一元素的 k 长度列表。用于随机抽样,无需更换。
返回一个新列表,其中包含来自填充的元素,同时保持原始填充不变。生成的列表按选择顺序排列,因此所有子切片也将是有效的随机样本。这允许抽奖获奖者(样本)分为大奖和第二名获奖者(子切片)。
人口中的成员不必是可散列的或唯一的。如果总体包含重复项,则每个匹配项都是样本中的一个可能选择。
可以一次指定一个重复元素,也可以使用可选的仅关键字计数参数指定重复元素。例如,等效于
sample(['red', 'blue'], counts=[4, 2], k=5)
sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)
若要从整数范围中选择示例,请使用 range() 对象作为参数。对于从大量人群中采样而言,这特别快速且节省空间: sample(range(10000000), k=60)
如果样本数量大于总体大小,则会引发值错误。
版本3.9中更改: 添加了计数参数。
自版本 3.9 起已弃用: 将来,人口必须是一个序列。不再支持 set 的实例。必须首先将集合转换为列表或元组,最好按确定性顺序转换,以便示例可重现。
实值分布 以下函数生成特定的实值分布。函数参数以分布方程中的相应变量命名,如常见数学实践中所用;这些方程中的大多数都可以在任何统计文本中找到。
random.random() 返回 [0.0, 1.0] 范围内的下一个随机浮点数。
random.uniform(a,b) 返回一个随机浮点数 N,使得 for 和 为 。a <= N <= ba <= bb <= N <= ab < a
终点值可能包含在范围内,也可能不包含在范围内,具体取决于等式中的浮点舍入。ba + (b-a) * random()
random.triangular(low,hight,model) 返回一个随机浮点数 N,使得 在这些边界之间具有指定的模式。下限和高限默认为零和一。mode 参数默认为边界之间的中点,给出对称分布。low <= N <= high
random.betavariate(alpha,beta) 贝塔分布。参数上的条件为 和 。返回值的范围介于 0 和 1 之间。alpha > 0beta > 0
random.expovariate(lambd) 指数分布。lambd 为 1.0 除以所需的均值。它应该是非零的。(该参数将被称为“lambda”,但这
x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) = --------------------------------------
math.gamma(alpha) * beta ** alpha
random.gauss(mu, sigma)
是Python中的保留词。如果 lambd 为正,则返回值的范围从 0 到正无穷大;如果 lambd 为负,则返回值的范围从负无穷大到 0。
random.gammavariate(alpha,beta) 伽玛分布。(不是伽马函数!参数上的条件为 和 。alpha > 0beta > 0
概率分布函数为:
正态分布,也称为高斯分布。mu 是平均值,西格玛是标准差。这比下面定义的 normalvariate() 函数略快。
多线程注意:当两个线程同时调用此函数时,它们可能会收到相同的返回值。这可以通过三种方式避免。1) 让每个线程使用不同的随机数生成器实例。2)在所有呼叫周围放置锁。3) 改用较慢但线程安全的 normalvariate() 函数。
random.lognormvariate(mu, sigma) 记录正态分布。如果取此分布的自然对数,则得到具有均值 mu 和标准差 sigma 的正态分布。mu 可以具有任何值,并且 sigma 必须大于零。
random.normalvariate(mu, sigma) 正态分布。mu 是平均值,西格玛是标准差。
random.vonmisesvariate(mu, kappa) mu 是平均角度,以 0 到 2pi 之间的弧度表示,kappa 是浓度参数,必须大于或等于零。如果 kappa 等于零,则此分布将减小到 0 到 2pi 范围内的均匀随机角。
random.paretovariate(alpha) 帕累托分布alpha 是形状参数。
random.weibullvariate(alpha,beta) 威布尔分布。alpha 是比例参数,beta 是形状参数。
替代生成器 类 random.Random 实现随机模块使用的默认伪随机数生成器的类。
自版本 3.9 起已弃用future,种子必须是以下类型之一:、int、float、str、bytes 或 bytearray NoneTypfuturee
类 random.SystemRandom 使用 os.urandom() 函数从操作系统提供的源生成随机数的类。并非在所有系统上都可用。不依赖于软件状态,并且序列不可重现。因此,seed() 方法没有效果,将被忽略。getstate() 和 setstate() 方法在调用时会引发 NotImplementedError。
关于再现性的说明 有时,能够重现伪随机数生成器给出的序列是很有用的。通过重用种子值,只要多个线程未运行,相同的序列就应该在运行到运行之间可重现。
大多数随机模块的算法和种子设定函数在Python版本中都会发生变化,但有两个方面保证不会改变:
如果添加了新的播种方法,则将提供向后兼容的播种机。
当兼容的播种机被赋予相同的种子时,生成器的方法将继续产生相同的序列。 random()基本示例:
>>> random()
# Random float: 0.0 <= x < 1.0
0.37444887175646646
>>> uniform(2.5, 10.0)
# Random float: 2.5 <= x <= 10.0
3.1800146073117523
>>> expovariate(1 / 5)
# Interval between arrivals averaging 5 seconds
5.148957571865031
>>> randrange(10)
# Integer from 0 to 9 inclusive
7
>>> randrange(0, 101, 2)
# Even integer from 0 to 100 inclusive
26
>>> choice(['win', 'lose', 'draw'])
# Single random element from a sequence
'draw'
>>> deck = 'ace two three four'.split()
>>> shuffle(deck)
# Shuffle a list
>>> deck
['four', 'two', 'ace', 'three']
>>> sample([10, 20, 30, 40, 50], k=4)
# Four samples without replacement
[40, 10, 50, 30]
Simulations:
>>>
>>> # Six roulette wheel spins (weighted sampling with replacement)
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']
>>> # Deal 20 cards without replacement from a deck
>>> # of 52 playing cards, and determine the proportion of cards
>>> # with a ten-value: ten, jack, queen, or king.
>>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20)
>>> dealt.count('tens') / 20
0.15
>>> # Estimate the probability of getting 5 or more heads from 7 spins
>>> # of a biased coin that settles on heads 60% of the time.
>>> def trial():
... return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
...
>>> sum(trial() for i in range(10_000)) / 10_000
0.4169
>>> # Probability of the median of 5 samples being in middle two quartiles
>>> def trial():
... return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500
...
>>> sum(trial() for i in range(10_000)) / 10_000
0.7958
统计学上的自举例子,使用带替换的再抽样来估计样本平均值的置信区间。
http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm
from statistics import fmean as mean
from random import choices
data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]
means = sorted(mean(choices(data, k=len(data))) for i in range(100))
print(f'The sample mean of {mean(data):.1f} has a 90% confidence '
f'interval from {means[5]:.1f} to {means[94]:.1f}')
重新取样包络试验的例子,以确定药物与安慰剂效果之间观察到的差异的统计学意义或P值。
例子来自丹尼斯-沙沙和曼达-威尔逊的《统计很简单》。 Example from "Statistics is Easy" by Dennis Shasha and Manda Wilson
from statistics import fmean as mean
from random import shuffle
drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]
placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]
observed_diff = mean(drug) - mean(placebo)
n = 10_000
count = 0
combined = drug + placebo
for i in range(n):
shuffle(combined)
new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])
count += (new_diff >= observed_diff)
print(f'{n} label reshufflings produced only {count} instances with a difference')
print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')
print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')
print(f'hypothesis that there is no difference between the drug and the placebo.')
多服务器队列的到达时间和服务交付的模拟。
from heapq import heapify, heapreplace
from random import expovariate, gauss
from statistics import mean, quantiles
average_arrival_interval = 5.6
average_service_time = 15.0
stdev_service_time = 3.5
num_servers = 3
waits = []
arrival_time = 0.0
servers = [0.0] * num_servers # time when each server becomes available
heapify(servers)
for i in range(1_000_000):
arrival_time += expovariate(1.0 / average_arrival_interval)
next_server_available = servers[0]
wait = max(0.0, next_server_available - arrival_time)
waits.append(wait)
service_duration = max(0.0, gauss(average_service_time, stdev_service_time))
service_completed = arrival_time + wait + service_duration
heapreplace(servers, service_completed)
print(f'Mean wait: {mean(waits):.1f} Max wait: {max(waits):.1f}')
print('Quartiles:', [round(q, 1) for q in quantiles(waits)])
另请参见Jake Vanderplas关于统计分析的视频教程,他只用了几个基本概念,包括模拟、抽样、洗牌和交叉验证。 经济学模拟 Peter Norvig的市场模拟,展示了本模块提供的许多工具和分布(高斯、均匀、抽样、贝塔维拉、选择、三角和兰德尔)的有效使用。
A Concrete Introduction to Probability (using Python) Peter Norvig的教程,包括概率论的基础知识,如何编写模拟,以及如何使用Python进行数据分析。
默认的 random() 返回 0.0 ≤ x < 1.0 范围内的 2-⁵³ 的倍数。所有这样的数字都是均匀分布的,并且完全可以作为Python的浮点数来表示。然而,在这个区间内许多其他可表示的浮点数是不可能选择的。例如,2-⁵³.0.05954861408025609的整数倍不是吗?
下面的配方采取了不同的方法。区间内的所有浮点数都是可能的选择。尾数来自2⁵²≤尾数<2⁵³范围内的整数的均匀分布。指数来自一个几何分布,其中小于-53的指数出现的频率是下一个较大指数的一半。
from random import Random
from math import ldexp
class FullRandom(Random):
def random(self):
mantissa = 0x10_0000_0000_0000 | self.getrandbits(52)
exponent = -53
x = 0
while not x:
x = self.getrandbits(32)
exponent += x.bit_length() - 32
return ldexp(mantissa, exponent)
类中的所有实值分布都将使用新方法:
>>>
>>> fr = FullRandom()
>>> fr.random()
0.05954861408025609
>>> fr.expovariate(0.25)
8.87925541791544
该配方在概念上等效于一种算法,该算法从 0.0 ≤ x < 1.0 范围内的所有 2⁻¹⁰⁷⁴ 的倍数中进行选择。所有这些数字都是均匀分布的,但大多数必须向下舍入到最接近的可表示Python浮点数。(值 2⁻¹⁰⁷⁴ 是最小的正非归一化浮点数,等于 。)math.ulp(0.0)
另请参阅生成伪随机浮点值,这是Allen B. Downey的一篇论文,描述了生成比随机()通常生成的更细粒度浮点的方法。
作者介绍