使用内置python包的np.random.uniform()和uniform()的区别



我使用np.random.uniform()在一个类中生成一个数字。令人惊讶的是,当我运行代码时,我在结果中看不到任何预期的变化。另一方面,当我从python内置包中使用uniform()时,我看到结果中的变化,这显然是正常的。

它们真的是相同的吗?还是在它们的实现中有什么棘手的地方?

提前感谢!

创建一个模块,例如blankpaper.py,只有两行代码

import numpy as np
np.random.seed(420)

然后,在主脚本中执行

import numpy as np 
import blankpaper 
print(np.random.uniform())

你应该得到完全相同的数字。

当模块或库设置np.random.seed(some_number)时,全局numpy.random.*函数的后面是global RandomState生成器的一个实例,重点是global

很有可能您正在导入的某些东西正在执行上述操作。

将主脚本更改为

import numpy as np
import blankpaper
rng = np.random.default_rng()
print(rng.uniform())

,你应该每次都得到新的数字。

default_rng是随机数类Generator的构造函数。如文档中所述,

这个函数不管理默认的全局实例。

在回答"[a]你是否先播下种子?"这个问题时,你说

是的,我正在使用它,但如果我不使用种子或更改种子号。我检查了好几次。

假设我们重新定义blankpaper.py以包含以下行

import numpy as np
def foo():
    np.random.seed(420)
    print("I exist to always give you the same number.")

,假设你的主脚本是

import numpy as np
import blankpaper
np.random.seed(840)
blankpaper.foo()
print(np.random.uniform())

那么你应该得到与执行第一个主脚本(答案的顶部)获得的相同的数字。

在本例中,种子的设置隐藏在blankpaper模块中的一个函数中,但如果blankpaper.foo是一个类,并且blankpaper.foo__init__()方法设置了种子,则会发生同样的事情。

所以全局种子的设置可以相当"隐藏"。

还需要注意的是,上述内容也适用于随机模块

中的函数

该模块提供的函数实际上是a的绑定方法随机的隐藏实例。随机类。您可以实例化拥有Random的实例来获得不共享状态的生成器。

因此,当random模块中的uniform()每次为您生成不同的数字时,很可能是因为您或其他模块设置了random模块中的函数共享的种子。

numpyrandom中,如果您的类或应用程序想要拥有自己的状态,请从numpy创建Generator的实例或从random创建Random的实例(或从SystemRandom创建加密安全随机性)。这将是您可以在应用程序中传递的内容。它的方法将是numpy.randomrandom模块中的函数,只有它们将有自己的状态(除非您显式地将它们设置为相等)。

最后,我并不是说这就是导致你的问题的原因(我不得不做一些推断,因为我看不到你的代码),但这是一个很可能的原因。

有任何问题请告诉我!

最新更新