我使用np.random.uniform()在类中生成一个数字。令人惊讶的是,当我运行代码时,我看不到预期结果中的任何变化。另一方面,当我从python内置包中使用uniform()时,我会看到结果中的变化,这显然是正常的。
它们真的是一样的吗?或者在它们的实现中有什么棘手的地方吗?
提前谢谢你!
发布于 2022-04-16 01:31:34
只使用两行代码创建一个模块,例如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的构造函数。正如文档所指出的,
此函数不管理默认全局实例。
在回答这个问题时,你说:“你是先种下种子吗?”
是的,我正在使用它,但是如果我不使用种子或者改变种子号,那就无关紧要了。我查过好几次了。
假设我们重新定义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__()方法设置了种子,也会发生同样的事情。
因此,这种全球种子的设置可能是相当“隐藏”的。
还请注意,上述内容也适用于随机模中的函数。
该模块提供的函数实际上是random.Random类隐藏实例的绑定方法。您可以实例化您自己的Random实例,以获得不共享状态的生成器。
因此,当来自uniform()模块的random每次为您生成不同的数字时,很可能是因为您或其他模块设置了由来自random模块的函数共享的种子。
在numpy和random中,如果您的类或应用程序希望拥有自己的状态,则从numpy创建Generator的实例或从random创建Random的实例(或用于密码安全随机性的SystemRandom )。这将是您可以在应用程序中传递的内容。它的方法将是numpy.random或random模块中的函数,只有它们将有自己的状态(除非您显式地将它们设置为相等)。
最后,我并不是说这正是导致您的问题的原因(我不得不做出一些推论,因为我看不到您的代码),但这是一个非常可能的原因。
如有任何问题或关注,请通知我!
https://stackoverflow.com/questions/71889951
复制相似问题