【问题标题】:run np.empty for the second time第二次运行 np.empty
【发布时间】:2017-06-16 08:32:47
【问题描述】:

在 Scipy 文档中写道:

函数 zeros 创建一个全为 0 的数组,函数 one 创建一个全为 1 的数组,函数 empty 创建一个初始内容是随机的且取决于内存状态的数组。默认情况下,创建的数组的dtype是float64。

所以我运行了这段代码:

import numpy as np
np.empty((1,2))

它的回报:

array([[  6.92892901e-310,   8.42664136e-317]])

所以它返回一个随机数,一切都很好。

但是,当我第二次(在那个 shell 中)运行该代码时,它返回一个零数组!

np.empty((1,2))
array([[ 0.,  0.]])

问题来了,为什么第二次返回零数组(而不是随机数)?

【问题讨论】:

    标签: python arrays numpy scipy ipython


    【解决方案1】:

    在这种情况下,文档的措辞似乎有点不幸。从适当的随机数生成器的意义上讲,它们并不意味着随机。如果您需要后者,您可以使用numpy.randomscipy.stats 中的功能之一。

    描述numpy.empty 一个更好的词将是“未定义”,这意味着用户不能对返回数组中最初的值做出任何假设。如果您知道无论如何都会覆盖其内容,empty 是创建数组的最便宜的方法。计算机只会为您获取一些内存。如果该内存尚未在该会话中使用,它可能会显得随机。但是您的计算机也会回收内存。

    我不得不承认我真的不知道回收的内存是什么样的,但有两种可能

    • 它包含之前使用它的程序碰巧写的东西
    • 或者操作系统出于安全原因用零覆盖了它

    这两种可能性都可以解释你所看到的。

    【讨论】:

      【解决方案2】:

      这不是随机的,它取决于您的计算机在请求数组空间时给NumPy 的内存字节中保存的内容。如果其中有除零以外的其他内容,则这些内容将使用请求的 dtype 进行解释(看似随机,但更好的词是不可预测的)。

      在您的示例中,您没有保存第一个数组,因此第一个数组的内存立即被重用。

      >>> import numpy as np
      >>> print(id(np.empty((20))))
      2545385324992
      >>> print(id(np.empty((20))))
      2545385324992
      

      现在出现了令人惊奇的部分:似乎 Python(或 NumPy 或您的操作系统)在将内存再次提供给 NumPy 之前将其归零。

      如果你创建一个比它更大的数组,它不会是“零”,因为它是从其他地方获取的:

      >>> print(np.empty((1, 2)))
      [[  1.25757479e-311   1.25757479e-311]]
      >>> print(np.empty((1, 3)))
      [[  4.94065646e-324   9.88131292e-324   1.25757705e-311]]
      

      【讨论】:

      • 有趣!我没想到它会是完全相同的记忆。但这种行为是否有保证?
      • @PaulPanzer 我几乎可以肯定归零和重用都是实现细节(因此不能保证)。但后者是有道理的,因为如果再次请求完全相同的“大小”,重用最近释放的内存可能会更有效,所以这不是不可能的。
      • 这真是令人费解。如果有任何充分的理由第二次将内存归零。他们为什么不第一次申请?
      猜你喜欢
      • 2020-03-28
      • 2018-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 2017-10-26
      相关资源
      最近更新 更多