每当调用rand()时,是否会自动调用numpy.random.RandomState()?

时间:2015-04-29 08:12:18

标签: python numpy random

像C ++这样的语言要求程序员设置随机数生成器的种子,否则它的输出将始终相同。但是,像numpy这样的库不需要您手动初始化种子。

例如,代码如下:

from numpy.random import rand
rand()

每次给出不同的结果。

这是否意味着每次致电numpy.random.RandomState(seed=None)时都会调用rand

2 个答案:

答案 0 :(得分:4)

  

这是否意味着每次调用rand时都会调用numpy.random.RandomState(seed=None)

不,这意味着RandomState在启动时播种一次。如果每次调用rand时重新播种,那么就无法明确地询问是否有可重复的模式。

Python stdlib的random模块也是如此。

而且,尽管你对C ++有什么看法,但对于C ++ stdlib的<random>函数,它的也是

所有这些都证明默认种子,如果你不做任何事情,来自系统时间或系统熵生成器(如大多数* nix系统上的/dev/random)。

对于C rand来说情况并非如此(C ++中仍然存在这种情况,尽管您应该将其视为已弃用的 * ),但仅仅因为C消失了要求启动必须相当于调用srand(1)

如果您对&#34;启动时的确切感兴趣&#34;适用于NumPy:

  • numpy.random模块的顶层(在您的代码中第一次运行import numpy.randomfrom numpy.random import something时),它会构建一个全局RandomState,默认参数(意思是seed=None)。
  • RandomState的初始化程序只是将seed参数传递给seed方法。
  • RandomState.seed在使用None进行调用时,会为您的平台使用适当的系统熵源(例如/dev/urandom)。
  • 当您致电顶级rand时,它会使用全局RandomState

*不是因为这个问题;它很容易记住在你的程序开始时调用srand。但PRNG显然不能保证周期长度超过32767,无偏差分布等等几乎对任何事情都是一个坏主意......

答案 1 :(得分:2)

numpy.random模块类似于Python标准库中的random模块,因为numpy.random中的函数是隐藏生成器对象的绑定方法,当您导入时,它会被实例化。模块。这个隐藏的numpy.random.RandomState实例目前存在于np.random.mtrand._rand中(尽管在未来的numpy版本中你不应该依赖它):

print(np.random.rand)
# <built-in method rand of mtrand.RandomState object at 0x7f50ced03660>

# note the same memory address of the RandomState object:
print(np.random.mtrand._rand)
# <mtrand.RandomState object at 0x7f50ced03660>

导入模块时,隐藏的RandomState实例将仅一次播种(除非您使用np.random.seed()显式设置种子)。如果每次调用rand()时都选择了新种子,那么将无法创建可重现的伪随机数序列。

情况如下:

# implicit RandomState created and seeded
from numpy import random

# # we could subsequently re-seed the hidden RandomState, e.g.:
# random.seed(None)

# different random variates
r1 = random.rand(1)
r2 = random.rand(1)
r3 = random.rand(1)
# ...

自动播种相当于np.random.RandomState(None),它使用一些与平台相关的随机源(通常在* nix上/dev/urandom)来设置种子。