Python中numpy.random和random.random之间的差异

时间:2011-08-11 17:05:55

标签: python random random-seed

我有一个Python的大脚本。我在其他人的代码中启发自己,所以我最终使用numpy.random模块来处理某些事情(例如,创建从二项分布中获取的随机数数组),在其他地方我使用模块{{1} }。

有人可以告诉我两者之间的主要区别吗? 在我看来,对于这两者中的每一个的文档网页,random.random只有更多的方法,但我不清楚随机数的生成是如何不同的。

我之所以要问是因为我需要将我的主程序播种用于调试目的。但除非我在导入的所有模块中使用相同的随机数生成器,否则它不起作用,这是正确的吗?

另外,我在这里读到了另一篇文章,关于不使用numpy.random的讨论,但我并不真正理解为什么这是一个如此糟糕的主意。如果有人解释我为什么会这样,我真的很感激。

4 个答案:

答案 0 :(得分:98)

你已经做了很多正确的观察!

除非你想为两个随机发生器播种,否则从长远来看选择一个发电机或其他发电机可能更简单。

对于numpy.random.seed(),主要的困难是它不是线程安全的 - 也就是说,如果你有many different threads of execution则使用它是不安全的,因为如果有两个不同的线程,它就不能保证工作同时执行该功能。如果您没有使用线程,并且如果您可以合理地预期将来不需要以这种方式重写您的程序,numpy.random.seed()应该没问题。如果有任何理由怀疑将来可能需要线程,那么从长远来看,按照建议和make a local instance of the numpy.random.Random class进行操作会更安全。据我所知,random.random.seed()是线程安全的(至少,我没有找到任何相反的证据)。

numpy.random库包含一些在科学研究中常用的额外概率分布,以及一些用于生成随机数据阵列的便利函数。 random.random库更轻一些,如果您没有进行科学研究或其他类型的统计工作,那么应该没问题。

否则,他们都使用Mersenne twister sequence来生成随机数,并且它们都是完全确定性的 - 也就是说,如果您知道一些关键信息,就可以绝对确定地预测{{ 3}}。因此,numpy.random或random.random都不适合任何what number will come next。但是因为序列非常长,所以在您不担心人们试图对数据进行逆向工程的情况下,两者都可以生成随机数。这也是必须为随机值设定种子的原因 - 如果你每次都在同一个地方开始,你将总是得到相同的随机数序列!

作为旁注,如果您执行需要加密级别随机性,那么如果您使用的是Python版本,则应使用serious cryptographic uses模块或secrets之类的模块早于Python 3.6。

答案 1 :(得分:8)

Python for Data Analysis开始,模块numpy.random补充了Python random,其功能可以从多种概率分布中有效地生成整个样本值数组。

相比之下,Python的内置random模块一次只能采样一个值,而numpy.random可以更快地生成非常大的采样值。使用IPython魔术函数%timeit可以看到哪个模块执行得更快:

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop

答案 2 :(得分:3)

种子的来源和使用的分布配置文件将影响输出 - 如果您正在寻找加密随机性,从os.urandom()播种将从设备聊天(即以太网或磁盘)获得几乎真实的随机字节(即BSD上的/ dev / random)

这样可以避免给出种子,从而生成确定的随机数。然而,随机调用然后允许你将数字拟合到一个分布(我称之为科学随机 - 最终你想要的是随机数的钟形曲线分布,numpy最好是在这个时候。

是的,坚持使用一台发电机,但决定你想要什么随机 - 随机,但是从分配曲线中随意地,或者在没有量子装置的情况下随机获得。

答案 3 :(得分:0)

令我惊讶的是 randint(a, b)numpy.random 中都存在 random 方法,但它们的上限行为不同。

random.randint(a, b) 返回一个随机整数 N,使得 a <= N <= brandrange(a, b+1) 的别名。它包含 brandom documentation

但是,如果您调用 numpy.random.randint(a, b),它将从低(包含)返回到高(不包含)。 Numpy documentation