python之random库


   源码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 序列的长度相同。
  weightscum_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长度列表。 用于无重复的随机抽样。
  返回包含来自总体的元素的新列表,同时保持原始总体不变。 结果列表按选择顺序排列,因此所有子切片也将是有效的随机样本。
  总体成员不必是 hashableunique 。 如果总体包含重复,则每次出现都是样本中可能的选择。
  重复的元素可以一个个地直接列出,或使用可选的仅限关键字形参 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 并在这些边界之间使用指定的modelowhigh边界默认为零和一。 mode 参数默认为边界之间的中点,给出对称分布。

15)random.betavariate(alpha, beta)

  功能:Beta 分布。 参数的条件是 alpha > 0beta > 0。 返回值的范围介于 0 和 1 之间。

16)random.expovariate(lambd)

  功能:指数分布。lambd 是 1.0 除以所需的平均值,它应该是非零的。如果 lambd 为正,则返回值的范围为 0 到正无穷大;如果 lambd 为负,则返回值从负无穷大到 0。

17)random.gammavariate(alpha, beta)

  功能:Gamma 分布。( 不是gamma 函数) 参数的条件是 alpha > 0beta > 0

18)random.gauss(mu, sigma)

  功能:高斯分布。mu 是平均值,sigma是标准差。 这比下面定义的 normalvariate()函数略快。
  多线程注意事项:当两个线程同时调用此方法时,它们有可能将获得相同的返回值。 这可以通过三种办法来避免。 1) 让每个线程使用不同的随机数生成器实例。 2) 在所有调用外面加锁。 3) 改用速度较慢但是线程安全的normalvariate() 函数。

19)random.lognormvariate(mu, sigma)

  功能:对数正态分布。 如果你采用这个分布的自然对数,你将得到一个正态分布,平均值为mu和标准差为 sigmamu 可以是任何值,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.
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Roar冷颜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值