【问题标题】:np.full(size, 0) vs. np.zeros(size) vs. np.empty()np.full(size, 0) vs. np.zeros(size) vs. np.empty()
【发布时间】:2022-03-07 20:47:06
【问题描述】:

如果您要选择以下三种初始化零数组的方法之一,您会选择哪一种以及为什么

my_arr_1 = np.full(size, 0) 

my_arr_2 = np.zeros(size)

my_arr_3 = np.empty(size)
my_arr_3[:] = 0

【问题讨论】:

  • 这正是np.zeros 的用途。为什么你会使用它?
  • 我实际上正在使用它。但是,我不确定这些方法中哪一种在时间和内存使用方面最有效!

标签: python arrays numpy


【解决方案1】:

我会使用np.zeros,因为它的名字。我永远不会使用第三个成语,因为

  1. 它需要两个语句而不是单个表达式和

  2. NumPy 人员更难优化。事实上,在 NumPy 1.10,np.zeros 仍然是最快的选择,尽管对索引进行了所有优化:

>>> %timeit np.zeros(1e6)
1000 loops, best of 3: 804 µs per loop
>>> %timeit np.full(1e6, 0)
1000 loops, best of 3: 816 µs per loop
>>> %timeit a = np.empty(1e6); a[:] = 0
1000 loops, best of 3: 919 µs per loop

更大的数组用于与@John Zwinck 的结果进行比较:

>>> %timeit np.zeros(1e8)
100000 loops, best of 3: 9.66 µs per loop
>>> %timeit np.full(1e8, 0)
1 loops, best of 3: 614 ms per loop
>>> %timeit a = np.empty(1e8); a[:] = 0
1 loops, best of 3: 229 ms per loop

【讨论】:

  • "full" 和 assignment 是相同的,当然我想提一下我更喜欢a[...] = 0 而不是a[:]。 zeros 现在告诉内核将内存归零。
  • 不,但它不在我的测量范围内:)
  • @seberg:基于此,以及 1e6 和 1e8 案例的时间,我猜 np.zeros() 最终会使用超出某个阈值的匿名 mmap()np.empty() 可能使用它也是,设置了MAP_UNINITIALIZED 标志),并且内存在第一次读/写之前没有归零 - 甚至没有正确分配,这使得时间或多或少无用。 (对所有测量中的数组执行例如np.sum() 可能会给出更合理的结果)
【解决方案2】:

绝对是np.zeros。它不仅是最惯用和最常用的方法,而且也是迄今为止最快的:

In [1]: size=100000000

In [3]: %timeit np.full(size, 0)
1 loops, best of 3: 344 ms per loop

In [4]: %timeit np.zeros(size)
100000 loops, best of 3: 8.75 µs per loop

In [5]: %timeit a = np.empty(size); a[:] = 0
1 loops, best of 3: 322 ms per loop

【讨论】:

  • 有趣的说明:如果数组形状不是一维的,
【解决方案3】:

np.zeros 如果要将数组初始化为零,则要快得多。如果只想初始化一个给定形状和类型的数组,而不关心数组中的初始条目,np.empty 会稍微快一些。

查看以下基本测试结果:

>>%timeit np.zeros(1000000)
7.89 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

>>%timeit np.empty(1000000)
7.84 µs ± 332 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

【讨论】:

  • 你在比较苹果和橙子。 np.zeros(n) 给出的结果与 np.empty(n) 不同。这已经在@FredFoo 的解决方案中进行了解释。
  • 好的,感谢您的纠正。所以如果只是初始化, np.empty 会稍微快一些;如果初始化为零,np.zero 会快得多。
  • 当然。但是有两个不同的问题:(1)不同的输出,(2)速度。在实践中,只有 (1) 很重要。
【解决方案4】:
np.zero():always 0
np.empty():Random number, depending on memory condition

你可以在campare看到以下内容

np.zeros( (3,4) )
array([[ 0.,  0.,  0.,  0.],
...    [ 0.,  0.,  0.,  0.],
...    [ 0.,  0.,  0.,  0.]])


np.empty((3,4))
array([[1.13224202e+277, 1.73151846e-077, 1.24374310e-047,1.30455491e-076],
       [3.92384790e+179, 6.01353875e-154, 3.12452337e-033,7.72229932e+140],
       [1.28654694e-320, 0.00000000e+000, 0.00000000e+000,0.00000000e+000]])

【讨论】:

    【解决方案5】:

    首先,我们应该了解这三者之间的区别,这有助于我们选择其中一个。

    1. np.zeros(size): 生成具有给定形状的全 0 数组。
    np.zeros(5)    #array([0., 0., 0., 0., 0.])
    
    1. np.empty(5): empty 创建一个数组,其初始内容是随机的,并且取决于内存的状态。
    np.empty(4)    #array([0.00000000e+000, 1.05915457e-311, 1.05915457e-311, 1.05915457e-311])
    
    1. np.full(size, fill_value): 返回一个给定形状和类型的新数组,用 fill_value 填充。
    np.full((2, 2), 10)      #array([[10, 10],
                                     [10, 10]])  
    

    所以,在这种情况下np.zeros(size) is obviously right choose and also the fast way to create an array filled with zeros.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      相关资源
      最近更新 更多