python random 和numpy random_Python中numpy.random和random.random之间的区别

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

有人可以告诉我两者之间的主要区别吗?

看一下这两个文档的文档网页,在我看来numpy.random只是有更多的方法,但是我不清楚随机数的生成方式是如何不同的。

我问的原因是因为我需要为调试目的播种我的主程序。 但是,除非我在要导入的所有模块中都使用相同的随机数生成器,否则它将无法正常工作吗?

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

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

除非您希望为两个随机生成器都作为种子,否则从长远来看选择一个或另一个生成器可能更简单。

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

numpy.random库包含一些科学研究中常用的额外概率分布,以及用于生成随机数据数组的几个便捷函数。 random.random库要轻一些,如果您不从事科学研究或其他统计工作,那应该很好。

否则,它们都使用Mersenne扭曲序列生成它们的随机数,而且它们都是完全确定性的-也就是说,如果您知道一些关键信息,则可以绝对确定地预测下一个数字。因此,numpy.random或random.random都不适合任何严重的加密用途。但是,由于序列非常长,因此在您不担心有人试图对数据进行反向工程的情况下,两者都适合生成随机数。这也是必须播种随机值的原因-如果每次都从同一位置开始,那么您将始终获得相同的随机数序列!

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

作为一个遥远的相关说明,有时有时不需要使用它们,因为梅森捻线器不会产生足以用于加密(和某些非常规的科学)目的的熵的随机序列。在极少数情况下,您通常需要Crypto.Random,它能够使用OS特定的熵源来生成质量不确定的随机序列,其质量要比单独random.random高。不过,您通常不需要这个。

谢谢Hannnele。您的见解确实非常有用!事实证明,我不能只使用一个随机数生成器(因为随机数不会产生二项式分布,所以它必须是numpy),因为我的程序的一部分调用了另一个使用随机数的程序。我将必须播种这两个生成器。

"如果知道现在有哪个数字,就可以绝对确定地预测下一个数字。"我认为这句话可能需要澄清。意思是,如果您知道生成器的内部状态,则可以重现序列-这是在生成生成器时执行的操作。给定生成器输出的单个数字,您将无法预测下一个数字。周期如此之大,您可能需要很长的数字序列才能计算出伪随机序列上的位置,从而预测下一个。

在用于数据分析的Python中,模块numpy.random对Python random进行了补充,该功能可以根据多种概率分布有效地生成样本值的整个数组。

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

1

2

3

4

5

6

7

8In [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

其他方法则不然。将np.random.randint(2)与random.randrange(2)进行比较,而NumPy则较慢。 NumPy:1.25 us,随机:891 ns。并且np.random.rand()和random.random()的关系相同。

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

这样可以避免您提供种子,从而避免产生确定性的随机数。但是,随机调用然后使您可以将数字拟合为一个分布(我称之为科学随机性-最终,您想要的只是一个随机数的钟形曲线分布,numpy最擅长于说明这一点。

所以,是的,坚持使用一个发生器,但是要确定您想要的随机数-随机,但是会偏离分布曲线,或者在没有量子设备的情况下尽可能地随机。

Paul非常感谢您,您的回答非常有用!我不是在寻找密码随机性,而是在做数学建模,伪随机数对我来说足够了。事实证明,由于我需要numpy进行二项式分布,并且我的程序调用了另一个使用random :(

你可能感兴趣的:(python,random,和numpy,random)