首页 > 解决方案 > 通过对随机大小的可变调用来控制 numpy 随机种子

问题描述

N我有一个模拟,每次迭代都需要生成随机数。但是,N根据模拟的状态而有所不同。因为N因人而异,以下调用会numpy.random()产生不同的结果。但是,我希望以下调用numpy.random()不受N.

我一直在通过(1)在调用之前生成一个大的随机整数numpy.random()然后(2)在调用之后将随机种子设置为这个整数来解决这个问题numpy.random()(见下文)。然而,这似乎很笨拙。

有没有更好的方法来控制不受参数影响的 numpy.random 状态size

import numpy as np
N=10
# set seed
np.random.seed(0)
# generate N numbers
a = np.random.normal(size=N)
# check its state
print(np.random.randint(1e4))

此调用randint()返回2599

# set seed
N = 1
np.random.seed(0)
# generate N numbers
b = np.random.normal(size=N)
# check its state
print(np.random.randint(1e4))

此调用randint()返回4859

潜在的解决方案:

N = 10
# set seed
np.random.seed(0)
# generate a large random integer
rand_int = np.random.randint(1e6)
# generate N numbers
b = np.random.normal(size=N)
# reset the seed
np.random.seed(rand_int)
# check its state
print(np.random.randint(1e4))

这个调用randint()返回5143,独立于N

标签: pythonnumpyrandom

解决方案


numpy.random.*函数使用在整个应用程序中共享的 PRNG(伪随机数生成器)的单个全局实例。在您的代码示例np.random.normal中,将此 PRNG 推进不同的次数,以便randint随后的调用输出不同的伪随机数。

相反,如果您的模拟的不同部分需要不同的随机数流,则不要依赖numpy.random.*的全局 PRNG 实例,而是使用两个或多个 PRNG 实例,每个实例都基于一个公共种子进行初始化。

NumPy 1.17 引入了一个新的随机数生成系统,并为此目的包括了几个工具。其中包括一个SeedSequence使用公共种子生成多个 PRNG 状态的Generator类,以及一个持有 PRNG 的类。新系统是一项更改 RNG 政策的提议的结果,该政策规定numpy.random.*通常不应再使用功能。这尤其是因为numpy.random.*在全局状态下运行。

NumPy 文档现在包含有关在新系统中播种多个 PRNG的详细信息。另请参阅我的一篇关于 PRNG 的文章中的“播种多个进程”。


推荐阅读