Python 中 numpy.random 和 random.random 的区别
- 2025-03-18 08:55:00
- admin 原创
- 45
问题描述:
我有一个很长的 Python 脚本。我从其他人的代码中获得了灵感,因此我最终numpy.random
在某些方面使用了该模块(例如,创建一个从二项分布中抽取的随机数数组),在其他地方我也使用了该模块random.random
。
有人能告诉我这两者之间的主要区别吗?查看这两个文档的网页,我觉得numpy.random
只是有更多的方法,但我不清楚随机数的生成有何不同。
我之所以问这个问题是因为我需要为调试目的播种我的主程序。但除非我在导入的所有模块中使用相同的随机数生成器,否则它不会起作用,对吗?
另外,我在另一篇文章中读到过关于不使用的讨论numpy.random.seed()
,但我真的不明白为什么这是一个坏主意。如果有人能向我解释为什么会这样,我将不胜感激。
解决方案 1:
您已经做出许多正确的观察!
除非您想同时为两个随机生成器设定种子,否则从长远来看,选择其中一个生成器可能更简单。但是如果您确实需要同时使用这两个生成器,那么您也需要同时为它们设定种子,因为它们会独立生成随机数。
对于numpy.random.seed()
,主要的困难在于它不是线程安全的 - 也就是说,如果您有许多不同的执行线程,那么使用它是不安全的,因为如果两个不同的线程同时执行该函数,则不能保证它能正常工作。如果您不使用线程,并且如果您有理由预期将来不需要以这种方式重写程序,那就numpy.random.seed()
应该没问题。如果有任何理由怀疑您将来可能需要线程,那么从长远来看,按照建议去做并创建类的本地实例numpy.random.Random
要安全得多。据我所知,random.seed()
是线程安全的(或者至少,我没有发现任何相反的证据)。
该numpy.random
库包含一些常用于科学研究的额外概率分布,以及一些用于生成随机数据数组的便利函数。该random.random
库更轻量级一些,如果您不从事科学研究或其他类型的统计工作,它应该没问题。
否则,它们都使用梅森旋转序列来生成随机数,并且它们都是完全确定性的 - 也就是说,如果你知道一些关键信息,就可以绝对确定地预测下一个数字是什么。 因此,numpy.random 和 random.random 都不适合任何严肃的加密用途。 但是因为序列非常长,所以在你不担心有人试图对你的数据进行逆向工程的情况下,两者都可以生成随机数。 这也是需要播种随机值的原因 - 如果你每次都从同一个地方开始,你总会得到相同的随机数序列!
附注:如果您确实需要加密级别的随机性,那么您应该使用secrets模块,或者如果您使用的 Python 3.6 之前的 Python 版本,则应该使用Crypto.Random之类的模块。
解决方案 2:
该模块从用于数据分析的 Python中numpy.random
补充了 Pythonrandom
函数,用于从多种概率分布中有效地生成整个样本值数组。
相比之下,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
解决方案 3:
令我惊讶的是该方法在和randint(a, b)
中都存在,但它们对于上限的行为有所不同。numpy.random
`random`
random.randint(a, b)
返回一个随机整数 N,使得a <= N <= b
。 的别名randrange(a, b+1)
。 它具有b
包容性。随机文档
但是如果你调用numpy.random.randint(a, b)
,它将返回低(包括)到高(不包括)。Numpy文档
解决方案 4:
种子的来源和使用的分布配置文件将影响输出 - 如果您正在寻找加密随机性,从 os.urandom() 播种将从设备聊天(即以太网或磁盘)中获得几乎真实的随机字节(即 BSD 上的 /dev/random)
这样可以避免您给出种子,从而生成确定性随机数。但是,随机调用允许您将数字拟合到分布中(我称之为科学随机性 - 最终您想要的只是随机数的钟形曲线分布,numpy 最擅长实现这一点。
所以是的,坚持使用一个生成器,但要决定你想要什么随机 - 随机,但肯定来自分布曲线,或者是在没有量子设备的情况下可以获得的随机数。
扫码咨询,免费领取项目管理大礼包!