【发布时间】:2018-09-23 12:50:56
【问题描述】:
重要修改:
如果您有时间测试下面的 sn-ps,请确保开始一个全新的会话或致电 np.random.seed(None) 一次。
背景:
我的印象是,np.random.randint() 之类的函数会为相同的随机状态绘制相同的一组数字(或者任何你称之为来自 np.random.get_state() 的输出)。
让我解释一下原因:
下面的 sn-p 使用np.random.randint() 生成 5 个介于 -10 和 10 之间的随机整数,并存储有关该过程的一些信息。我命名为“状态”的是数组中的前 5 个数字,该数组存储在 np.random.get_state() 返回的元组的第二个元素中。
片段 1
# 1. Imports
import pandas as pd
import numpy as np
# 2. describe random state by
# retrieving the five first numbers
# in the array in the second element
# of the tuple returned by np.random.get_state()
randomState = np.random.get_state()
state = np.random.get_state()[1][:5]
# 3. generate random numbers
randints = np.random.randint(-10, 10, size = 5)
# 4. organize and present findings
df = pd.DataFrame.from_dict({'state':state, 'randints':randints})
print(df)
运行此代码一次,您将获得如下第一个输出部分所示的结果。请注意,数字本身将与我的不同,因为没有设置随机种子。重要的是三组输出的内部逻辑。如果你多次运行相同的 sn-p,你会发现一些我认为非常奇怪的东西:
输出1:一些随机数和一个随机状态:
randints state
0 -10 2871458436
1 7 4226334938
2 1 179611462
3 -9 3145869243
4 5 317931933
到目前为止,一切都很好!我们有 5 个随机整数和 5 个代表随机状态的数字。 再次运行同样的 sn-p,你会得到这样的结果:
输出 2:新的随机数和新的随机状态:
randints state
0 1 727254058
1 7 1473793264
2 4 2934556005
3 1 721863250
4 -6 3873014002
现在您似乎有了一个新的随机状态和 5 个新的随机数。所以看起来,我的假设仍然成立。 但是每次我尝试这个时,当你第三次运行相同的代码时,事情就会变得很奇怪。看看这个:
输出 3:新的随机数和与之前相同的随机状态:
randints state
0 8 727254058
1 -4 1473793264
2 -1 2934556005
3 -10 721863250
4 -1 3873014002
如您所见,我的假设显然是错误的。 真正在这里发生了什么?
总结:
- 为什么
np.random.randint()会为同一个随机状态返回不同的整数? - 为什么运行此 sn-p 会在第一次和第二次运行时产生不同的随机状态,但在第二次和第三次运行时返回相同的随机状态?
感谢您的任何建议!
我的系统:
- Python 3.6.0
- IPython 5.1.0
- Numpy 1.11.3
- Spyder 3.2.7
- Windows 64
附录:
如果您将相同的过程包装到一个函数中并运行两次以上,您将得到相同的结果。
片段 2 - 与包含在函数中的片段 1 相同
def rnumbers(numbers, runs):
df_out = pd.DataFrame()
runs = np.arange(runs)
for r in runs:
print(r)
state = np.random.get_state()[1][:numbers]
# 4. generate random numbers
randints = np.random.randint(-10, 10, size = numbers)
# 5. organize and present findings
df_temp = pd.DataFrame.from_dict({'state_'+str(r+1):state, 'randints_'+str(r+1):randints})
df_out = pd.concat([df_out, df_temp], axis = 1)
return df_out
df = rnumbers(10,3)
print(df)
输出:
randints_1 state_1 randints_2 state_2 randints_3 state_3
0 4 3582151794 -5 1773875493 7 1773875493
1 -7 2910116392 -8 2402690106 3 2402690106
2 -8 3435011439 3 1330293688 4 1330293688
3 1 486242985 4 847834894 2 847834894
4 -3 4214584559 4 4209159694 -2 4209159694
5 4 752109368 -3 2673278965 1 2673278965
6 -10 3726578976 8 2475058425 4 2475058425
7 8 1510778984 -5 3758042425 0 3758042425
8 -2 4202558983 -5 2381317628 0 2381317628
9 4 1514856120 6 3177587154 -7 3177587154
【问题讨论】:
-
np.random.seed(None)应该做什么?删除它,您的输出将保持一致。至于片段二 - 我无法确认您的输出。 Mine is the same for all three rounds. -
我编辑了这个问题。这里重要的一点是尚未设置随机种子。这只是我提出这个问题之前的众多测试之一。是的,我知道
np.random.seed(None) -
1.它不应该。 2.你确定随机状态是一样的吗?尝试打印出整个
randomState。对于不同的运行,我得到了不同的 randomState(注意:不是你的第二个 sn-p,因为你已经设置了 random.seed,所以应该为不同的运行提供相同的 randomState,就像 T 先生一样。) -
在此处查看 Robert Kern 的回复:stackoverflow.com/questions/5836335/… 和此处:stackoverflow.com/questions/37224116/…
-
np.random.get_state()中的 pos 编号[2]在不同的运行中会发生变化。那(我在这里猜)取之前数组中的相应值来设置随机状态。要验证,请使用np.random.set_state(x)设置会话的随机状态,其中 x 是复制粘贴的,并将数组部分转换为 dtype='uint32' 的 np.array,用于 unsigned int32。然后,将 pos 值设置为 1,并使用数组中除 [1] 之外的其他值。您将获得相同的randint或任何其他随机函数。现在,如果你改变 pos 或 pos 指示的值,输出就会改变。