`

Python:Random模块学习

 
阅读更多

Python:Random模块学习

 

在使用python生成随机数时,肯定会想到random模块。random模块实现了各种分布的伪随机(Pseudo-Random)数生成,我们这次来学习下Python的random模块。

对于整数来说,random模块很简单,这个也是很常用的伪随机生成使用方法;但是对于序列(Sequence)来说,random模块能够随机选取序列元素、生成序列的随机分布,或者随机不重复抽样等。

random模块实现的分布主要包括:uniform、normal(Gaussian)、lognormal、negative exponential、gamma、beta等;还有个von Mises,这个是产生角度分布,算法思想可以参考wiki:http://en.wikipedia.org/wiki/Von_Mises_distribution

 

在random模块中,定义了如下几个常量: 

NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
TWOPI = 2.0*_pi
LOG4 = _log(4.0)
SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53        # Number of bits in a float
RECIP_BPF = 2**-BPF

  

我们先看下random模块定义的方法: 

>>> import random;
>>> for method in dir(random):
...   print method;
... 

  

定义了三个类: 

Random:
SystemRandom:
WichmannHill :

这三个类都能产生随机数,其中Random是常用的随机数产生算法,我们主要讨论的随机数产生都是该类的方法;WichmannHill和SystemRandom都继承了Random类,WichmannHill的random方法使用了和Random类相似的随机方法,该算法主要依赖于seed值,有兴趣的同学可以看下理论,我看实现难度不大,但是理论估计是有点难度;SystemRandom是使用操作系统的random产生函数,如unix依赖于/dev/urandom,windows依赖于CryptGenRandom等。 

 

下面我们来看下random模块提供的方法: 

random.seed([x]): 

设置random包的seed值,该值对于生成随机数至为重要,如果你不设置的话,默认取系统时间。

  

random.random() 

返回随机数,值范围是[0.0,1.0),该方法在后面的各种分布中多次出现,所以该随机数生成算法是random模块的基础。我们来看下random函数的源码: 

def random(self):
   x, y, z = self._seed
   x = (171 * x) % 30269
   y = (172 * y) % 30307
   z = (170 * z) % 30323
   self._seed = x, y, z
   return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 

该算法实现看起来简单,如果想深入理解这个随机数算法的原理,可以参考An efficient and portable pseudo-random number generator(Applied Statistics 31 (1982) 188-190)这篇文章,该文章后面的算法实现和random的源码略有不同,文章参考这里:http://www2.imperial.ac.uk/~hohs/S9/2007-2008/wichmannhill.pdf

  

random.expovariate(lambd)

指数分布

 

random.gammavariate(alpha, beta)

Gamma分布,要求alpha>0且beta>0,注意这个不是Gamma函数。当然在计算过程中用到了Gamma函数。Gamma分布的详细信息参考wiki:http://en.wikipedia.org/wiki/Gamma_distribution

 

 

random.gauss(mu, sigma)
random.normalvariate(mu, sigma) 

这两个都是产生Gauss分布,两者采用不同的思路产生,前者使用统计意义上的计算,后者是依据标准的正态分布定义产生。前者生成速度还要快点,不过在多线程场景下使用要自己加锁控制并发。 

 

random.lognormvariate(mu, sigma):

对数级别的正态分布。

 

random.betavariate(alpha, beta)

Beta Distribution,要求alpha>0beta>0,依赖于gamma分布,通过gamma分布函数生成。

 

random.triangular(low, high, mode)

产生三角分布函数,关于Triangular Distribution的详细信息见http://en.wikipedia.org/wiki/Triangular_distributionwiki里面有比较详细的讨论;看源码会发现该函数的生成同样依赖于random()函数。

 

random.uniform(a, b)

产生[a,b]的均匀分布,该分布产生利用了random()函数,实际上产生的值为a+(b-a)*random()

 

random.paretovariate(alpha):Pareto Distribution
random.vonmisesvariate(mu, kappa):Von Mises Distribution,是针对角度的分布。
random.weibullvariate(alpha, beta):Weibull Distribution 

这三个分布稍显专业,平时都不怎么用。

 

将Python作用到Sequence上,可以看下下面几个函数的效果

random.choice(seq)
random.sample(population, k)
random.shuffle(x[, random])

 

choice函数从seq中随机选择一个元素,sample函数从元素列表中选取k个不重复元素,shuffle函数则对元素列表进行一次随机排列。看下示例:

>>> bits=['a','b','c','d','e','f','g']
>>> random.choice(bits)
'a'
>>> random.choice(bits)
'c'
>>> random.sample(bits,3)
['c', 'b', 'e']
>>> random.sample(bits,3)
['g', 'a', 'c']
>>> random.shuffle(bits)
>>> bits
['a', 'f', 'd', 'g', 'b', 'e', 'c']

 

random.random()
random.randrange(stop)
random.randrange(start, stop[, step])
random.randint(a, b)
random.getrandbits(k) 

random函数产生[0.0,1.0)的随机数,这个在上面提到过;randrange函数是在提到的range(start,end,step)中随机选择;randint函数是在[a,b]中选择,注意两边都是闭区间;getrandbits函数实在bit级别上进行控制,控制每个bit上的随机量。

>>> random.random()
0.6216895046152143
>>> random.randrange(10)
7
>>> random.randrange(5,10)
9
>>> random.randrange(5,10)
6
>>> random.randrange(5,10)
7
>>> random.randrange(5,10)
5
>>> random.randrange(5,10,2)
5
>>> random.randrange(5,10,2)
9
>>> random.randrange(5,10,2)
7
>>> random.randint(1,100)
49
>>> random.randint(1,100)
22
>>> random.getrandbits(5)
27
>>> random.getrandbits(5)
27
>>> random.getrandbits(5)
7
>>> random.getrandbits(50)
259336269183598
>>> random.getrandbits(500)
2123294400168802339423947306484820684208555438132242308767915648686014450077945137455581839262813894933829601172344940098461036686745618482209213922214
>>> random.getrandbits(5000)
4034754137539484179299467597527391507546381474148526154395421207380075606134559180138703425120094793323534549803288574253400061961405474748312233157619180389178319042116709667737968426875719453232825587709299171195574278743656906955409390042725992518977600085740467686975785820692459295094963664868994212901792068886664992509467663579527691907093450609832530263379958186539108800219479153927035711354075963574379567702705107895056023508996779148121923936388548341378859868882424925192771844170677816283953086457527992241139927429905498724725234373412588522642913731667566323782617498119281849336962492061749751663018412752756985945190973968626062918960920916813960732895100632389147211487593464557043805295027860687336511022864551102551287702441650416601162438483314529829096068674259579299557425952074299390480479779787510272694343411355085195312144186003575867190677050695130041384874117375485556935211062489182801151796266461330635349790915122810079710159825931951294785611281623200060903422400093055307371277330083371368887743322247273016355323686859209112857576218973944225428147564652781736490029302922410573312453153416182209839876163339188176414458934726982720923448475009661073041932910018380017325457354357313544645084438508127883399927917698522570586118494954794329286952111267534963812167557444992442451658941414640398737575936221194957286718271011604437241627690160697999192659641775460024935972380618868777518058797753473526196799809754689345865056290961953738953134889706900308020180214258

 

random.getstate()
random.setstate(state) 

staterandom包内部的一个状态表示,[VERSION,_seed, gauss_next]数组表示,如果你想设置state,请将VERSION设置为1

 

random.jumpahead(n)

random内部维护了生成随机数的流程,jumpahead函数会重置函数生成流程,使得能够在同样的状态下生成下一步的随机函数,不受已经生成的随机数的影响。这个函数在单线程情况下影响不大,但是对于多线程,能够控制在每个线程中随机数生成的初始状态一致。在stackoverflow上有个帖子http://stackoverflow.com/questions/2546039/how-should-i-use-random-jumpahead-in-python比较详细的解释了这个问题,在多线程情况下使用随机数时需要这个的问题在后面的帖子中也有提到,可以详细看下。

 

random包提供的内容还是挺丰富的,除去产生随机数外,对于Sequence的操作也能较好的减小工作量,特别是choicesampleshuffle函数提供的功能。

 

既然提到了random函数,我们在深入理解下random函数的生成。在前面提到,unix系统下random的生成依赖于/dev/urandom,实际上,另外一个产生随机数的文件是/dev/random。两者产生的随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。两者的不同点是后者在不能产生随机数会阻塞(block),而前者不会。所以使用/dev/random比使用/dev/urandom产生的随机数要慢,但是随机性要好。如果使用随机数要求不是特别高的话,/dev/urandom产生随机数足够。

 

关于python的随机数random模块的学习结束。在这里一定要区分random模块和Random类。后者是random模块中定义的类,准确的说,random模块中提供的方法都是Random类中的方法;如果你想使用SystemRandom和WichmannHill类,就需要自己初始化。  

 

分享到:
评论

相关推荐

    python的random模块及加权随机算法的python实现方法

    一般不必特别去设定seed,Python会自动选择seed。 •random.random() 用于生成一个随机浮点数n,0 <= n 于生成一个指定范围内的随机浮点数,生成的随机整数a于生成一个指定范围内的整数,a为下限,b为上限,生成...

    Python内置random模块生成随机数的方法

    Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入random模块。 import random 下面介绍下Python内置的random模块的几种生成随机数的方法。 1、random.random()随机生成 0 到 1 之间的浮点数...

    Python使用random模块生成随机数操作实例详解

    本文实例讲述了Python使用random模块生成随机数操作。分享给大家供大家参考,具体如下: 今天在用Python编写一个小程序时,要用到随机数,于是就在网上查了一下关于Python生成各种随机数的方法,现将其总结如下: ...

    Python3 中 random模块.docx

    Python中的random模块用于生成随机数。 下面具体介绍random模块的功能: 1.random.random() 用于生成一个0到1的 随机浮点数:0 1 import random 2 a = random.random() 3 print (a) 2.random.uniform(a,b) 用于...

    你真的了解Python的random模块吗?

    主要介绍了Python的random模块的相关内容,具有一定借鉴价值,需要的朋友可以参考下。

    基于Python中random.sample()的替代方案

    补充知识:Python: random模块的随即取样函数:choice(),choices(),sample() choice(seq): 从seq序列中(可以是列表,元组,字符串)随机取一个元素返回 choices(population, weights=None, *

    Python中random模块用法实例分析

    本文实例讲述了Python中random模块用法。分享给大家供大家参考。具体如下: import random x = random.randint(1,4); y = random.choice(['appale','banana','cherry','durian']); print(x,y); 运行结果如下: (2,...

    Python中random模块常用方法的使用教程

    Python 的random模块包含许多随机数生成器。 random是Python标准库之一,直接导入即可使用。本文介绍random中常用方法的用法。 一、生成随机的整数 # coding=utf-8 import random print(random.randint(1, 5)) ...

    python模块

    * DBM-style 数据库模块:python提供了打了的modules来支持UNIX DBM-style数据库文件。dbm模块用来读取标准的UNIX-dbm数据库文件,gdbm用来读取GNU dbm数据库文件,dbhash用来读取Berkeley DB数据库文件。所有的这些...

    Python中random模块生成随机数详解

    Python中的random模块用于生成随机数。下面介绍一下random模块中最常用的几个函数。 random.random random.random()用于生成一个0到1的随机符点数: 0 <= n < 1> b,则生成的随机数n: a <= n <= b。如果 a ...

    python 中random模块的常用方法总结

    主要介绍了python 中random的常用方法总结的相关资料,需要的朋友可以参考下

    详解Python基础random模块随机数的生成

    Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入random模块。 import random 下面介绍下Python内置的random模块的几种生成随机数的方法。 1、random.random() 随机生成 0 到 1 之间的浮点数...

    Python的random模块

    random模块 random模块提供了一些生成随机数的函数,一些介绍为了简单省略random. random():返回在范围大于等于0.0,且小于1.0内的随机浮点数 randrange(stop):返回大于等于0,且小于 randrange(start, stop[, ...

    python:numpy.random模块生成随机数

    python中的numpy.random模块提供了常用的随机数生成方法,下面简要总结。 按均匀分布生成随机数 rand 功能 按照均匀分布,在[0,1)内生成随机数。 接口 Docstring: rand(d0, d1, ..., dn) Random values in a given ...

    Python3.5内置模块之random模块用法实例分析

    本文实例讲述了Python3.5内置模块之random模块用法。分享给大家供大家参考,具体如下: 1、random模块基础的方法 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:ZhengzhengLiu import random print...

    Python随机数random模块使用指南

    random 模块是Python自带的模块,除了生成最简单的随机数以外,还有很多功能。 random.random() 用来生成一个0~1之间的随机浮点数,范围[0,10 >>> import random >>> random.random() 0.5038461831828231 random...

    Python random模块制作简易的四位数验证码

    主要介绍了Python random模块制作简易的四位数验证码,文中给大家提到了python中random模块的相关知识,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics