Python numpy.random.seed()是否每次都给出相同的随机数?

Python numpy.random.seed()是否每次都给出相同的随机数?,python,numpy,random,Python,Numpy,Random,我知道如果我使用相同的种子,numpy.random.seed(seed)将输出相同的数字。我的问题是,这会随着时间的推移而改变吗?如果我明天再调用它,它还会输出与昨天相同的一组随机数吗 文档描述了所使用的PRNG。显然,在最近的过去,有一个从到的部分转换。如果您想要一致性,您需要: 修复使用的PRNG,以及 确保您使用的是本地句柄(例如,RandomState,Generator),这样对其他外部库所做的任何更改都不会因为调用np.random全局变量而导致混乱 在本例中,我们使用了更新的AP

我知道如果我使用相同的种子,
numpy.random.seed(seed)
将输出相同的数字。我的问题是,这会随着时间的推移而改变吗?如果我明天再调用它,它还会输出与昨天相同的一组随机数吗

文档描述了所使用的PRNG。显然,在最近的过去,有一个从到的部分转换。如果您想要一致性,您需要:

  • 修复使用的PRNG,以及
  • 确保您使用的是本地句柄(例如,
    RandomState
    Generator
    ),这样对其他外部库所做的任何更改都不会因为调用
    np.random
    全局变量而导致混乱
  • 在本例中,我们使用了更新的API,它提供了各种PRNG的选择

    from numpy.random import Generator, PCG64
    
    rg = Generator(PCG64(1234))
    
    可按如下方式使用:

    >>> rg.uniform(0, 10, 10)
    array([9.767, 3.802, 9.232, 2.617, 3.191, 1.181, 2.418, 3.185, 9.641,
           2.636])
    
    如果我们多次重新运行它(即使在同一个REPL中!),我们将始终获得相同的随机数生成器。PCG64与MT19937一样,提供以下保证:

    兼容性保证

    PCG64保证固定种子和将始终生成相同的随机整数流

    尽管@user2357112支持Monica指出,对使用随机整数序列的随机API函数的更改(例如,
    np.random.Generator.uniform
    )在技术上仍然是可行的,但可能性不大

    为了生成多个生成器,可以使用
    SeedSequence.spawn(k)
    生成
    k
    不同的s。这对于一致的并发计算非常有用:

    from numpy.random import Generator, PCG64, SeedSequence
    
    sg = SeedSequence(1234)
    rgs = [Generator(PCG64(s)) for s in sg.spawn(10)]
    

    传统的
    RandomState
    API和模块级随机生成函数(实际上是隐藏的RandomState方法)具有:

    兼容性保证

    使用固定种子的固定位生成器和使用相同参数对“RandomState”方法的固定系列调用将始终产生相同的结果,直到舍入错误,除非值不正确。RandomState被有效冻结,只接收Numpy内部更改所需的更新。更实质性的变化,包括算法改进,保留给生成器

    来自相同种子的相同调用序列将产生相同的最大舍入错误结果,除非旧结果有问题(例如,如果结果表明某个方法没有产生它应该产生的分布)


    这是以陷入糟糕的设计选择为代价的。例如,
    numpy.random.choice
    with
    replace=False
    由于一个不好的实现而非常慢,如果不破坏向后兼容性,就无法修复该实现
    numpy.random.Generator.choice
    没有这个问题,因为它不受相同的兼容性保证的约束。

    如果升级到较新版本的
    numpy
    ,我怀疑它是否保证生成相同的随机数序列。我很高兴被证明是错的。@markransem我的经验和你说的是一致的。它可以在numpy/python的不同版本中更改。文档描述了所使用的PRNG。显然,有一个从MT19937到PCG64的部分转换。如果您想要一致性,您需要修复正在使用的PRNG,并确保您使用的是本地句柄(例如,
    RandomState
    Generator
    ),这样对外部库的任何更改都不会因为调用
    np.random
    全局变量而把事情搞砸。