我使用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
模块中的函数共享的种子。
在numpy
和random
中,如果您的类或应用程序想要拥有自己的状态,请从numpy
创建Generator
的实例或从random
创建Random
的实例(或从SystemRandom
创建加密安全随机性)。这将是您可以在应用程序中传递的内容。它的方法将是numpy.random
或random
模块中的函数,只有它们将有自己的状态(除非您显式地将它们设置为相等)。
最后,我并不是说这就是导致你的问题的原因(我不得不做一些推断,因为我看不到你的代码),但这是一个很可能的原因。
有任何问题请告诉我!