Python中numpy.random和random.random的区别

2024-04-26 12:24:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本。我在别人的代码中得到了启发,因此我最终使用了numpy.random模块来处理一些事情(例如,创建一个从二项式分布中获取的随机数数组),而在其他地方,我使用了random.random模块。

有人能告诉我这两者的主要区别吗? 看看这两个文档的网页,在我看来,numpy.random有更多的方法,但是我不清楚随机数的生成是如何不同的。

我之所以问这个问题是因为我需要在主程序中植入种子,以便进行调试。但是除非我在导入的所有模块中使用相同的随机数生成器,否则它不会工作,对吗?

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


Tags: 模块方法代码文档numpy脚本网页地方
3条回答

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

这将避免您给出一个种子,从而生成确定性随机数。然而,随机调用允许你将这些数字拟合成一个分布(我称之为科学随机性——最终你想要的只是随机数的钟形曲线分布,numpy最擅长这样做。

所以是的,坚持使用一个生成器,但要决定你想要什么样的随机-随机,但不受分布曲线的限制,或者不使用量子器件就可以得到任意。

Python for Data Analysis开始,模块numpy.random用函数来补充Python random,从而有效地从多种概率分布中生成样本值的整个数组。

相比之下,Python的内置random模块一次只采样一个值,而numpy.random可以更快地生成非常大的样本。使用IPython magic函数%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

你已经提出了许多正确的意见!

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

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

numpy.random库包含一些在科学研究中常用的额外概率分布,以及一些用于生成随机数据数组的方便函数。这个random.random库稍微轻一点,如果你不做科学研究或其他类型的统计工作,应该没问题。

否则,它们都使用Mersenne twister sequence来生成随机数,而且它们都是完全确定的——也就是说,如果你知道一些关键信息位,就有可能绝对确定地预测what number will come next。因此,numpy.random和random.random都不适合任何serious cryptographic uses。但由于序列非常长,在您不担心有人试图对您的数据进行反向工程的情况下,这两种方法都可以生成随机数。这也是需要为随机值设定种子的原因——如果每次都从同一个地方开始,那么您将始终获得相同的随机数序列!

顺便说一下,如果您需要加密级别的随机性,那么应该使用secrets模块,如果您使用的是Python 3.6之前的Python版本,则应该使用Crypto.Random之类的模块。

相关问题 更多 >