Python Numpy:循环中的随机数

4

我有这样的代码并使用Jupyter-Notebook

for j in range(timesteps):    
    a_int = np.random.randint(largest_number/2) # int version

我得到了随机数,但是当我尝试将代码的一部分移动到函数中时,每次迭代都会收到相同的数字。

def create_train_data():        
    np.random.seed(seed=int(time.time()))     
    a_int = np.random.randint(largest_number/2) # int version
    return a

for j in range(timesteps):    
    c = create_train_data()  

为什么会发生这种情况,如何解决?我认为可能是Jupyter-Notebook中的进程导致的。


2
这是因为您正在使用缓存结果的Jupyter。 - ninesalt
3个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5
有问题的代码行是:
np.random.seed(seed=int(time.time()))

由于您正在执行一个相当快速完成的循环,调用int()在时间上减少了您的随机种子,使其在整个循环中成为相同的数字。如果您真的想要手动设置种子,则以下是更健壮的方法。

def create_train_data():   
    a_int = np.random.randint(largest_number/2) # int version
    return a

np.random.seed(seed=int(time.time()))
for j in range(timesteps):
    c = create_train_data()
请注意,种子只被创建一次,然后在整个循环中使用,这样每次调用随机整数时,种子都会改变而不被重置。 请注意,numpy已经处理了伪随机种子。通过使用它,您不会获得更多的随机结果。手动设置种子的常见原因是确保可重复性。您可以在程序开头(笔记本的顶部)将种子设置为某个固定整数(我在许多教程中看到42),然后所有计算都遵循该种子。如果有人想要验证您的结果,算法的随机性不能成为混淆因素。

不,你说的不对,我之前使用的代码没有种子,所以我加上了但是没有得到结果。 - Vladimir Shebuniayeu
1
@Vladimircape,当我注释掉随机种子行时,得到的结果是随机的。 - Jeremy
@Jeremy Hhh,非常奇怪。因为当我只是在新的默认笔记本中创建时,它也可以正常运行,但在我的整个示例中,它不起作用,我会尝试提供整个代码。 - Vladimir Shebuniayeu

0
汉斯·马斯格雷夫的答案非常好,如果您满意伪随机数的话。伪随机数对大多数应用程序来说是很好的,但如果用于加密,则存在问题。 获取一个真正的随机数的标准方法是在拉取数字之前使用系统时间对随机数生成器进行种子处理,就像您尝试过的那样。然而,正如汉斯·马斯格雷夫所指出的那样,如果将时间转换为int,则会得到以秒为单位的时间,这在整个循环中很可能是相同的。种子RNG的正确解决方案是:
def create_train_data():        
    np.random.seed()     
    a_int = np.random.randint(largest_number/2) # int version
    return a
这是因为如果你在np.random.seed中不传递参数(或者传递None),Numpy已经使用计算机时钟或其他随机源来生成种子:

参数:seed{None,int,array_like},可选的随机种子用于初始化伪随机数生成器。可以是介于02 ** 32-1之间的任何整数,这样的整数数组(或其他序列)或None(默认值)。如果seedNone,则RandomState将尝试从/ dev / urandom(或Windows类似物)读取数据,否则从时钟进行种子处理。

但这完全取决于您的应用程序。请注意文档中的警告:

警告:本模块的伪随机生成器不应用于安全目的。有关安全或加密用途,请参见secrets模块。


不行,绝对不行。你在回答中包含的文档部分甚至已经说明了:“可选的随机种子用于初始化伪随机数生成器”。再聪明选择的种子也无法改变你正在使用伪随机数生成器的事实。 - user2699
你只是从伪随机数生成器中获取单个数字。 - Joooeey
1
仍然不行。输出完全取决于种子。如果您有一些数字来源,每次需要一个单独的数字时都是完全不可预测的,那么您实际上不需要伪随机数生成器。 - user2699
当然,这是真的。但是,在跨平台方面实现这一点需要付出相当大的努力,为什么不使用一个可以为您完成此操作的库呢?它已经在np.random库中实现了。该库有其弱点(如果经常使用,则无法保证/dev/urandom是随机的),但应该比使用PRNG序列更好。 - Joooeey
除了那个丑陋的 hack 之外,主要原因是 np.random 中的一些文档声明:“警告:此模块的伪随机生成器不应用于安全目的。对于安全或密码学用途,请参阅 secrets 模块。” - user2699
OP没有说明目的是安全性。 - Joooeey

0
其他答案都正确地指出了这是由于种子的原因。如果您查看SciPy文档,您将看到种子用于创建可预测的随机序列。然而,我认为另一个关于种子的问题的回答提供了更好的概述,说明它的作用以及何时/在哪里使用它。numpy.random.seed(0)是什么意思?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,