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

Lau*_*ura 91 python random random-seed

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

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

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

另外,我在这里读到了另一篇文章,关于不使用的讨论numpy.random.seed(),但我真的不明白为什么这是一个坏主意.如果有人解释我为什么会这样,我真的很感激.

Han*_*ele 109

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

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

因为numpy.random.seed(),主要的困难是它不是线程安全的 - 也就是说,如果你有许多不同的执行线程,那么使用它是不安全的,因为如果两个不同的线程同时执行该函数,它就不能保证工作.如果您没有使用线程,并且如果您可以合理地预期将来不需要以这种方式重写您的程序,那么numpy.random.seed()应该没问题.如果有任何理由怀疑你可能需要在未来的线程,它是更安全的长远做的建议,并作出的本地实例numpy.random.Random.据我所知,random.random.seed()是线程安全的(至少,我没有找到任何相反的证据).

numpy.random库包含一些常用于科学研究的额外概率分布,以及一些用于生成随机数据阵列的便利函数.该random.random图书馆是一个小更轻便,而且如果你不这样做科研或其他种类的工作,在统计应该罚款.

否则,他们都使用梅森扭转序列来生成他们的随机数,并且它们都是完全确定性的 - 也就是说,如果你知道一些关键信息位,就可以绝对确定地预测下一个数字.因此,numpy.random和random.random都不适用于任何严重的加密用途.但是因为序列非常长,所以在您不担心人们试图对数据进行逆向工程的情况下,两者都可以生成随机数.这也是必须为随机值播种的原因 - 如果你每次都在同一个地方开始,你将总是得到相同的随机数序列!

作为旁注,如果你确实需要加密级随机性,你应该使用秘密模块,或者像Crypto.Random这样的东西,如果你使用的是早于Python 3.6的Python版本.

  • 作为一个远距离相关的注释,有时需要使用***,因为Mersenne twister不会产生足以用于加密(和一些不寻常的科学)目的的随机熵序列.在极少数情况下,您经常需要[Crypto.Random](https://www.dlitz.net/software/pycrypto/apidoc/Crypto.Random.random-module.html),它能够使用OS特定的熵源生成比单独从`random.random'获得的质量高得多的非确定性随机序列.但是,你通常不需要这个. (12认同)
  • "如果你知道你现在拥有哪个号码,那么就可以绝对肯定地预测接下来会有多少数字." 我认为这种说法可能需要一些澄清.意思是如果您知道生成器的*内部状态*,您可以重现序列 - 这是您在为生成器播种时所执行的操作.给定生成器的单个数字输出,您无法预测下一个数字.周期非常大,您可能需要一长串数字才能计算伪随机序列的位置,从而预测下一个序列. (2认同)

lmi*_*asf 11

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
Run Code Online (Sandbox Code Playgroud)

  • 其他方法则不然。将 `np.random.randint(2)` 与 `random.randrange(2)` 进行比较,NumPy 是**慢的**。NumPy:1.25 us 和 Random:891 ns。以及 `np.random.rand()` 和 `random.random()` 的相同关系。 (5认同)