python之random库
- 1 random库简介
- 2 random库中函数简介
- 1)random.random()
- 2)random.seed(a=None, version=2)
- 3)random.getstate()
- 4)random.setstate(state)
- 5)random.randbytes(n)
- 6)random.randrange(start, stop[, step])
- 7)random.randint(a, b)
- 8)random.getrandbits(k)
- 9)random.choice(seq)
- 10)random.choices(population, weights=None, cum_weights=None, k=1)
- 11)random.shuffle(x[, random])
- 12)random.sample(population, k, counts=None)
- 13)random.uniform(a, b)
- 14)random.triangular(low, high, mode)
- 15)random.betavariate(alpha, beta)
- 16)random.expovariate(lambd)
- 17)random.gammavariate(alpha, beta)
- 18)random.gauss(mu, sigma)
- 19)random.lognormvariate(mu, sigma)
- 20)random.normalvariate(mu, sigma)
- 21)random.vonmisesvariate(mu, kappa)
- 22)random.paretovariate(alpha)
- 23)random.weibullvariate(alpha, beta)
- 3 实际应用
源码: Lib/random.py
1 random库简介
该模块实现了各种分布的伪随机数生成器。
几乎所有模块函数都依赖于基本函数 random() ,它在半开放区间 [0.0,1.0) 内均匀生成随机浮点数。Python 使用 Mersenne Twister 作为核心生成器。 它产生 53 位精度浮点数,周期为 2**19937-1 ,其在 C 中的底层实现既快又线程安全。 Mersenne Twister 是现存最广泛测试的随机数发生器之一。 但是,因为完全确定性,它不适用于所有目的,并且完全不适合加密目的。
在程序中使用需要添加:import random
2 random库中函数简介
1)random.random()
功能:在半开放区间 [0.0,1.0) 内均匀生成随机浮点数
>>> import random
>>> print(random.random())
0.22236454038203257
>>> print(random.random())
0.34447890508044166
>>> print(random.random())
0.7549491127645795
>>> print(random.random())
0.4869192522525654
2)random.seed(a=None, version=2)
功能:初始化随机数生成器。
如果 a 被省略或为 None,则使用当前系统时间,所以每次的结果才不同。 如果操作系统提供随机源,则使用它们而不是系统时间。
>>> import random
>>> random.seed()
>>> print(random.random())
0.14018892109223613
>>> import random
>>> print(random.random())
0.45087033581188407
>>> import random
>>> print(random.random())
0.014014319804547481
可以在调用其他随机模块函数之前调用此函数:生成同样的结果
>>> import random
>>> random.seed(10)
>>> print(random.random())
0.5714025946899135
>>> random.seed(10)
>>> print(random.random())
0.5714025946899135
>>> random.seed(10)
>>> print(random.random())
0.5714025946899135
3)random.getstate()
功能:返回捕获生成器当前内部状态的对象。 这个对象可以传递给 setstate()
来恢复状态。
4)random.setstate(state)
功能:state
是从之前调用 getstate()
获得的,并且 setstate()
将生成器的内部状态恢复到getstate()
被调用时的状态(重现伪随机数)。
>>> import random
>>> x = random.getstate()
>>> random.random()
0.4288890546751146
>>> random.random()
0.5780913011344704
>>> random.random()
0.20609823213950174
>>> random.setstate(x)
>>> random.random()
0.4288890546751146
>>> random.random()
0.5780913011344704
>>> random.random()
0.20609823213950174
5)random.randbytes(n)
功能:生成 n 个随机字节。
6)random.randrange(start, stop[, step])
功能:从 range(start, stop, step) 返回一个随机选择的元素。
>>> random.randrange(0,100,2)
34
其中start和step可以省略。
>>> random.randrange(100)
83
>>> random.randrange(100)
20
>>> random.randrange(100)
4
7)random.randint(a, b)
功能:返回随机整数 N 满足 a <= N <= b。相当于 randrange(a, b+1,1)。
8)random.getrandbits(k)
功能:返回具有k 个随机比特位的非负 Python 整数。
>>> random.getrandbits(2)
2 #2位二进制:00(0),01(1),10(2),11(3)
>>> random.getrandbits(8)
125
9)random.choice(seq)
功能:从非空序列seq
返回一个随机元素。 如果 seq
为空,则引发IndexError
。
>>> print(random.choice("string"))
r
>>> print(random.choice([1,2,3,4]))
1
>>> print(random.choice([1,2,3,4]))
2
>>> print(random.choice(['剪刀', '石头', '布']))
布
>>> random.choice(['win', 'lose', 'draw'])
'lose'
10)random.choices(population, weights=None, cum_weights=None, k=1)
功能:从population
中选择替换,返回大小为 k 的元素列表。 如果 population 为空,则引发 IndexError。
如果指定了 weight 序列,则根据相对权重进行选择。 或者,如果给出 cum_weights 序列,则根据累积权重(可能使用itertools.accumulate()
计算)进行选择。 例如,相对权重[10, 5, 30, 5]
相当于累积权重[10, 15, 45, 50]
。 在内部,相对权重在进行选择之前会转换为累积权重,因此提供累积权重可以节省工作量。
如果既未指定 weight
也未指定cum_weights
,则以相等的概率进行选择。 如果提供了权重序列,则它必须与 population
序列的长度相同。
weights
或 cum_weights
可使用random()
所返回的能与 float 值进行相互运算的任何数字类型(包括 int、float、Fraction 但不包括 Decimal)。 权重为负值的行为未有定义。 如果权重为负值则将引发 ValueError
。
>>> random.choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['black', 'red', 'red', 'red', 'black', 'black']
>>> def trial():
return random.choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
>>> sum(trial() for i in range(10000)) / 10000
0.4251
11)random.shuffle(x[, random])
功能:将序列x
随机打乱位置。
>>> items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> random.shuffle(items)
>>> print(items)
[9, 4, 0, 3, 5, 2, 8, 7, 1, 6]
>>> deck = 'ace two three four'.split()
>>> random.shuffle(deck)
>>> print(deck)
['two', 'ace', 'four', 'three']
12)random.sample(population, k, counts=None)
功能:返回从总体序列或集合中选择的唯一元素的 k
长度列表。 用于无重复的随机抽样。
返回包含来自总体的元素的新列表,同时保持原始总体不变。 结果列表按选择顺序排列,因此所有子切片也将是有效的随机样本。
总体成员不必是 hashable
或 unique
。 如果总体包含重复,则每次出现都是样本中可能的选择。
重复的元素可以一个个地直接列出,或使用可选的仅限关键字形参 counts
来指定。 例如,sample([‘red’, ‘blue’], counts=[4, 2], k=5) 等价于 sample([‘red’, ‘red’, ‘red’, ‘red’, ‘blue’, ‘blue’], k=5)。
要从一系列整数中选择样本,请使用 range() 对象作为参数。 对于从大量人群中采样,这种方法特别快速且节省空间:sample(range(10000000), k=60) 。
如果样本大小大于总体大小,则引发 ValueError
。
>>> random.sample('12345',3)
['1', '3', '2']
>>> random.sample([1,2,3,4],3)
[3, 1, 4]
>>> random.sample((1,2,3,4),3)
[2, 4, 3]
>>> random.sample(range(10000000), 60)
[5503999, 7293232, 3752487, 84029, 9141075, 732710, 5564284, 5359032, 4070533, 1340919, 4391726, 7517131, 6791291, 9778583, 2654693, 6552961, 8317477, 4050158, 8813974, 4558245, 8725992, 8096592, 8386594, 1053166, 2790202, 8210536, 7741699, 6729842, 2277684, 7053734, 9081381, 9813581, 5859115, 9037333, 6506544, 8219086, 2781602, 9373766, 7404570, 1655093, 6965458, 592534, 47486, 7358123, 8982831, 1089524, 848473, 5865951, 1555976, 2550338, 1824629, 7618170, 8137878, 2337060, 7694707, 7323436, 8407267, 7500883, 5758432, 4347338]
>>> dealt = random.sample(['tens', 'low cards'], counts=[16, 36], k=20)
>>> print(dealt.count('tens') / 20)
0.45
13)random.uniform(a, b)
功能:返回一个随机浮点数 N ,当 a <= b 时 a <= N <= b ,当 b < a 时 b <= N <= a 。
取决于等式 a + (b-a) * random() 中的浮点舍入,终点 b 可以包括或不包括在该范围内。
>>> random.uniform(2.5,10.0)
9.234561517204892
>>> random.uniform(10.0,2.5)
4.765972394966746
14)random.triangular(low, high, mode)
功能:返回一个随机浮点数 N ,使得 low <= N <= high 并在这些边界之间使用指定的mode
。low
和 high
边界默认为零和一。 mode
参数默认为边界之间的中点,给出对称分布。
15)random.betavariate(alpha, beta)
功能:Beta 分布
。 参数的条件是 alpha > 0
和 beta > 0
。 返回值的范围介于 0 和 1 之间。
16)random.expovariate(lambd)
功能:指数分布。lambd
是 1.0 除以所需的平均值,它应该是非零的。如果 lambd
为正,则返回值的范围为 0 到正无穷大;如果 lambd 为负,则返回值从负无穷大到 0。
17)random.gammavariate(alpha, beta)
功能:Gamma 分布
。( 不是gamma 函数
) 参数的条件是 alpha > 0
和 beta > 0
。
18)random.gauss(mu, sigma)
功能:高斯分布。mu
是平均值,sigma
是标准差。 这比下面定义的 normalvariate()
函数略快。
多线程注意事项:当两个线程同时调用此方法时,它们有可能将获得相同的返回值。 这可以通过三种办法来避免。 1) 让每个线程使用不同的随机数生成器实例。 2) 在所有调用外面加锁。 3) 改用速度较慢但是线程安全的normalvariate()
函数。
19)random.lognormvariate(mu, sigma)
功能:对数正态分布。 如果你采用这个分布的自然对数,你将得到一个正态分布,平均值为mu
和标准差为 sigma
。 mu
可以是任何值,sigma
必须大于零。
20)random.normalvariate(mu, sigma)
功能:正态分布。 mu
是平均值,sigma
是标准差。
21)random.vonmisesvariate(mu, kappa)
功能:冯·米塞斯分布。mu 是平均角度,以弧度表示,介于0和 2**pi 之间,kappa
是浓度参数,必须大于或等于零。 如果kappa
等于零,则该分布在 0 到 2*pi 的范围内减小到均匀的随机角度。
22)random.paretovariate(alpha)
功能:帕累托分布。 alpha
是形状参数。
23)random.weibullvariate(alpha, beta)
功能:威布尔分布。 alpha
是比例参数,beta
是形状参数。
3 实际应用
statistical bootstrapping 的示例,使用重新采样和替换来估计一个样本的均值的置信区间:
# 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}')
The sample mean of 49.0 has a 90% confidence interval from 40.1 to 58.1
使用 重新采样排列测试来确定统计学显著性或者使用p-值来观察药物与安慰剂的作用之间差异的示例:
>>> 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 = 10000
>>> 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')
10000 label reshufflings produced only 14 instances with a difference
>>> print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')
at least as extreme as the observed difference of 13.0.
>>> print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')
The one-sided p-value of 0.0014 leads us to reject the null
>>> print(f'hypothesis that there is no difference between the drug and the placebo.')
hypothesis that there is no difference between the drug and the placebo.
多服务器队列的到达时间和服务交付模拟:
from heapq import heappush, heappop
from random import expovariate, gauss
from statistics import mean, median, stdev
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
for i in range(100_000):
arrival_time += expovariate(1.0 / average_arrival_interval)
next_server_available = heappop(servers)
wait = max(0.0, next_server_available - arrival_time)
waits.append(wait)
service_duration = gauss(average_service_time, stdev_service_time)
service_completed = arrival_time + wait + service_duration
heappush(servers, service_completed)
print(f'Mean wait: {mean(waits):.1f}. Stdev wait: {stdev(waits):.1f}.')
print(f'Median wait: {median(waits):.1f}. Max wait: {max(waits):.1f}.')
### result ###
Mean wait: 19.3. Stdev wait: 22.2.
Median wait: 12.3. Max wait: 171.3.