116

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

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

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

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

4

4 回答 4

141

您已经做出了许多正确的观察!

除非您想为两个随机生成器播种,否则从长远来看,选择一个或另一个生成器可能更简单。但是,如果您确实需要同时使用两者,那么是的,您还需要同时为它们播种,因为它们彼此独立地生成随机数。

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

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

否则,它们都使用梅森捻线器序列来生成它们的随机数,而且它们都是完全确定的——也就是说,如果你知道一些关键信息,就可以绝对确定地预测接下来会出现什么数字。出于这个原因, numpy.random 和 random.random 都不适合任何严重的加密用途。但是由于序列非常非常长,在您不担心有人试图对您的数据进行逆向工程的情况下,两者都可以生成随机数。这也是需要播种随机值的原因——如果你每次都从同一个地方开始,你总是会得到相同的随机数序列!

附带说明一下,如果您确实需要加密级别的随机性,则应该使用secrets模块,或者如果您使用的是 Python 3.6 之前的 Python 版本,则应该使用Crypto.Random 之类的东西。

于 2011-08-11T17:56:07.223 回答
12

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
于 2017-05-08T01:37:05.817 回答
3

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

这将避免您提供种子并因此生成确定性随机数。然而,随机调用然后允许您将数字拟合到分布(我称之为科学随机性 - 最终您想要的只是随机数的钟形曲线分布,numpy 最擅长于此。

所以,是的,坚持使用一个发生器,但决定你想要什么随机 - 随机,但绝对来自分布曲线,或者在没有量子设备的情况下尽可能随机。

于 2011-08-11T18:25:33.970 回答
0

令我惊讶的是,该randint(a, b)方法同时存在于numpy.randomrandom中,但它们对上限有不同的行为。

random.randint(a, b)返回一个随机整数 N 使得a <= N <= b. 的别名randrange(a, b+1)。它具有b包容性。随机文件

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

于 2021-03-06T22:58:29.647 回答