【问题标题】:Python Numpy: Random number in a loopPython Numpy:循环中的随机数
【发布时间】:2019-02-22 17:33:19
【问题描述】:

我有这样的代码并使用 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 中的过程

【问题讨论】:

  • 这是因为您使用的是缓存结果的 Jupyter

标签: python numpy random


【解决方案1】:

有问题的代码行是

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),然后所有计算都从该种子开始。如果有人想验证您的结果,算法的随机性不能成为混淆因素。

【讨论】:

  • 不,你不正确,我之前使用了没有种子的代码,这就是为什么我放了但没有得到结果
  • @Vladimircape,当我注释掉随机种子行时,我得到随机结果
  • @Jeremy Hhh,很奇怪。因为当我也只是在新的默认笔记本中制作它时,它也可以,但是在我的整个示例中,它不起作用,我将尝试提供整个代码
【解决方案2】:

其他答案是正确的,因为它是因为种子。如果您查看Documentation From SciPy,您会看到种子用于创建可预测的随机序列。但是,我认为另一个关于种子的问题的以下答案可以更好地概述它的作用以及为什么/在哪里使用它。 What does numpy.random.seed(0) do?

【讨论】:

    【解决方案3】:

    如果您对伪随机数感到满意,Hans Musgrave 的回答会非常棒。伪随机数适用于大多数应用程序,但如果用于加密,则会出现问题。

    获取一个真正随机数的标准方法是在提取数字之前为随机数生成器播种系统时间,就像您尝试过的那样。但是,正如 Hans Musgrave 指出的那样,如果您将时间转换为 int,您将获得以秒为单位的时间,这在整个循环中很可能是相同的。使用时间播种 RNG 的正确解决方案是:

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

    这是因为 Numpy 已经使用计算机时钟或其他随机源作为种子,如果您不向 np.random.seed 传递参数(或 None):

    参数: seed{None, int, array_like},可选随机种子 初始化伪随机数生成器。可以是任意整数 在02**32 - 1 之间,一个数组(或其他序列) 这样的整数,或None(默认值)。如果seedNone,那么 RandomState 将尝试从/dev/urandom(或 Windows 模拟)如果可用或从时钟种子否则。

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

    警告不应使用此模块的伪随机生成器 出于安全目的。有关安全或加密用途,请参阅 秘密模块。

    【讨论】:

    • 没有。就是不行。您在答案中包含的文档部分甚至指出:“用于初始化 pseudo-random 数字生成器的可选随机种子”。再多巧妙选择的种子也不会改变您使用伪随机数生成器这一事实。
    • 不过,您只是从伪随机数生成器中提取了一个数字。
    • 还是没有。输出完全取决于种子。如果您有一些完全不可预测的数字来源来播种伪随机数生成器,每次您需要一个数字时,那么您实际上并不需要伪随机数生成器。
    • 当然是这样。然而,以跨平台的方式实现这一点需要付出相当大的努力,所以为什么不使用一个为你做这件事的库。它已经在np.random 库中实现。该库有其弱点(/dev/urandom 不能保证如果大量使用是随机的),但它应该比使用 PRNG 序列更好。
    • 嗯,主要原因(除了丑陋的 hack)将是 np.random 中的一些文档,其中指出“警告:此模块的伪随机生成器不应用于安全目的。有关安全或加密用途,请参阅秘密模块。"
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2016-12-29
    • 2018-10-29
    • 1970-01-01
    • 2018-03-18
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多