一致地创建相同的随机numpy数组


89

我正在等待另一个开发人员完成一段代码,该代码将返回一个形状为(100,2000)的np数组,其值为-1,0或1。

同时,我想随机创建一个具有相同特征的数组,以便可以在开发和测试中抢先一步。问题是我希望这个随机创建的数组每次都相同,这样我就不会在每次重新运行过程时都在不断更改其值的数组上进行测试。

我可以像这样创建数组,但是有一种方法可以创建它,使其每次都相同。我可以腌制然后解开物体,但是想知道是否还有另一种方法。

r = np.random.randint(3, size=(100, 2000)) - 1

Answers:


84

只需给随机数生成器添加固定值即可,例如

numpy.random.seed(42)

这样,您将始终获得相同的随机数序列。


43
numpy.random.seed()当我不注意时,有人偷偷使用了该功能。:-)我特意将其保留在原始模块之外。我建议人们使用自己的RandomState对象实例并传递这些对象。
罗伯特·克恩

6
罗伯特是numpy的主要贡献者。我认为应该给他一些意见。
弃用

10
@不赞成使用:我感谢罗伯特的工作,但他的工作并不能代替提出建议的理由。此外,如果numpy.random.seed()不鼓励使用,则应在文档中提及。显然,NumPy的其他贡献者不同意罗伯特的观点。完全没有冒犯的意图,我只是很好奇。
Sven Marnach

13
这与使用random.seed和使用random.RandomPython标准库中的对象相同。如果使用random.seednumpy.random.seed,则将在代码中以及在您正在调用的任何代码中或在与您的会话相同的会话中运行的任何代码中植入所有随机实例。如果那些事情实际上取决于那些事情是随机的,那么您就会遇到问题。如果部署设置随机种子的代码,则会引入安全漏洞。
asmeurer 2014年

3
@asmeurer为安全起见,使用伪随机数生成器的任何人可能都不知道他们在做什么。
2016年

191

numpy.random.RandomState()使用选择的种子创建自己的实例。不要使用,numpy.random.seed()除非要解决那些不允许您传递自己的RandomState实例的不灵活的库。

[~]
|1> from numpy.random import RandomState

[~]
|2> prng = RandomState(1234567890)

[~]
|3> prng.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

[~]
|4> prng2 = RandomState(1234567890)

[~]
|5> prng2.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

7
您有什么建议的理由吗?这有什么错numpy.random.seed()?我知道它不是线程安全的,但是如果您不需要线程安全,那真的很方便。
Sven Marnach 2011年

52
主要是养成良好的习惯。您现在可能不需要独立的流,但是可能需要从现在起六个月。如果您编写库以直接使用的方法numpy.random,则以后将无法创建独立的流。为了控制PRNG流而编写库也更加容易。总是有多种进入图书馆的方法,每种方法都应有一种控制种子的方法。遍历PRNG对象比依靠是一种更干净的方法numpy.random.seed()。不幸的是,此评论框太短,无法包含更多示例。:-)
Robert Kern

25
描述罗伯特原理的另一种方法是:使用numpy.random.seed使用全局变量来保持PRNG状态,并且此处使用适用于全局变量不好的相同标准原因。
罗比·巴萨克

9
如果您希望PRNG独立,则不要添加任何种子。只需numpy.random.RandomState()不带参数使用。这将使用从您的操作系统工具中获得的唯一值来播种状态(/dev/urandom在UNIX计算机和Windows上等效)。如果numpy.random.RandomState(1234567890)不适合您,请准确显示您键入的内容以及错误消息。
罗伯特·肯恩

5
这不是一个好主意。numpy.random.RandomState()不带参数使用以获得最佳结果。
罗伯特·克恩

3

如果您要使用其他依赖于随机状态的函数,则不仅可以设置种子和总体种子,还应创建一个函数以生成数字的随机列表,并将种子设置为函数的参数。这不会干扰代码中的任何其他随机生成器:

# Random states
def get_states(random_state, low, high, size):
    rs = np.random.RandomState(random_state)
    states = rs.randint(low=low, high=high, size=size)
    return states

# Call function
states = get_states(random_state=42, low=2, high=28347, size=25)

3

重要的是要了解什么是随机生成器的种子以及何时/如何在代码中设置它(例如,请在此处查看有关种子的数学含义的详细说明)。

为此,您需要通过以下操作设置种子:

random_state = np.random.RandomState(seed=your_favorite_seed_value)

然后,重要的是从random_state而不是np.random生成随机数。即您应该这样做:

random_state.randint(...)

代替

np.random.randint(...) 

这将创建一个新的RandomState()实例,并基本上使用您的计算机内部时钟来设置种子。


2

我只是想澄清有关@Robert Kern答案的一些内容,以防万一不清楚。即使您确实使用,RandomState您也必须在每次调用numpy随机方法时都要初始化它,就像在Robert的示例中那样,否则您将获得以下结果。

Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> prng = np.random.RandomState(2019)
>>> prng.randint(-1, 2, size=10)
array([-1,  1,  0, -1,  1,  1, -1,  0, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([-1, -1, -1,  0, -1, -1,  1,  0, -1, -1])
>>> prng.randint(-1, 2, size=10)
array([ 0, -1, -1,  0,  1,  1, -1,  1, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([ 1,  1,  0,  0,  0, -1,  1,  1,  0, -1])
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.