(numpy)个随机种子有范围吗?

时间:2018-06-21 14:37:32

标签: python numpy random scope

我的问题与What is the scope of a random seed in Python?有关。 对于上述问题,需要说明的是,模块Random()中有一个(隐藏的)全局random实例。

1)我想澄清的是,在一个模块中设置随机种子是否会导致它成为 other 模块中的随机种子,以及是否需要注意某些事情。

例如: 给定:moduleA.py,moduleB.py

moduleA.py:

import random 
import moduleB
random.seed(my_seed)
moduleB.randomfct()

moduleB.py:

import random 
def randomfct():
    #do_things_using_random

moduleB是否也使用my_seed,还是我必须将种子传递给moduleB.py并重新设置?

2)设置随机种子/导入的顺序是否起作用?

例如在moduleA.py中:

import random 
random.seed(my_seed)
import moduleB

3)设置numpy个随机种子也是这种情况,例如np.random.seed(42)

3 个答案:

答案 0 :(得分:3)

CPython random.py实现非常易读。我建议您看看:https://github.com/python/cpython/blob/3.6/Lib/random.py

无论如何,该版本的python创建一个全局random.Random()对象,并将其直接分配给random模块。该对象包含一个seed(a)方法,当您调用random.seed(a)时该方法acts as a module function。因此,种子状态会在整个程序中共享。

1)是。 moduleAmoduleB使用相同的种子。在random中导入moduleA会创建全局random.Random()对象。在moduleB中重新导入它只会为您提供相同的模块并维护最初创建的random.Random()对象。

2)否。不是您所举的示例,但总的来说,这很重要。在设置moduleB中的种子之前,您可以使用moduleA,这样就不会设置种子。

3)很难说。更复杂的代码库。也就是说,我认为它的工作方式相同。 numpy的作者确实必须 try 来使其工作方式不同于python实现中的工作方式。

通常,如果您担心种子状态,建议您创建自己的随机对象并将其传递以生成随机数。

答案 1 :(得分:1)

因此,回答第一个问题:

  

moduleB是否也使用my_seed,还是我必须将种子传递给moduleB.py并重新设置?

是的,例如,运行以下命令:

ModuleA:

import moduleb
import random 
random.seed(0)
my_random()

ModuleB

import random
def my_random():
    print(random.randint(0,5))

设置种子后,它将始终打印3。 一般规则是必须运行的主要python模块应调用random.seed()函数,这将创建一个种子,该种子在所有导入的模块之间共享。 仅当您从其他模块再次显式调用random.seed时,此更改才会更改。

问题2:

  

设置随机种子/导入的顺序是否起作用?

不,不是。除非您在设置种子之前调用random函数。

问题3:

  

设置numpy随机种子也是这种情况,例如np.random.seed(42)?

因此,使用np.random.seed()带来的问题是它们不是线程安全的,这就是为什么它们的行为不同。可以在以下位置找到更多详细信息: This Stackoverflow answer

答案 2 :(得分:1)

在jupyter笔记本中,random.seed似乎具有单元格范围。 例如,需要在两个连续的单元格中都指定random.seed(1),以使用以下代码获得相同的结果:

单元格1:

np.random.seed(1)
np.random.random_sample(4)

单元2:

np.random.seed(1)
np.random.random(4)