np.empty与np.zeros的速度差异

8

我正在使用numpy 1.14.3版本和python 2.7.12版本。

参考这个问题,我发现使用np.zeros和np.empty初始化数组的速度差异很大,但输出结果是相同的。

import numpy as np
r = np.random.random((50, 100, 100))
z = np.zeros(r.shape)
e = np.empty(r.shape)
np.allclose(e, z)

这返回True。然而,计时函数%timeit给出非常不同的结果:

%timeit z = np.zeros(r.shape)

进行10000次循环,最佳结果为3次测试的平均每次143微秒。

%timeit e = np.empty(r.shape)

1000000次循环,3次取最佳结果:每次循环1.83微秒

以上提到的先前被接受的答案指出,np.zeros始终是更好的选择,而且速度更快。

既然np.empty比np.zeros快80倍并且返回相同的答案,为什么不使用它呢?

编辑: 正如user2285236所指出的那样,颠倒初始化ze的顺序会破坏相等性,因为它会覆盖同一内存区域。


2
np.empty 不保证返回一个全是零的数组。 - user2357112
此外,如果您仔细查看您链接的问题,您会发现提问者已经理解了这一点,并手动将np.empty返回值归零。 - user2357112
是的,我明白,在以前的numpy版本中,需要将数组清零。现在,似乎默认返回全零矩阵。有什么变化吗? - Mike
1
我认为你得到了零,因为你在z = np.zeros(r.shape)之后立即调用了np.empty。改变顺序,你就不会再得到np.allclose的True了。 - ayhan
user2285236 是正确的。调换顺序会搞砸事情。我会编辑帖子以反映这一点。 - Mike
对我来说,随着数组大小的增加,我得到更多的零:(2,3,5)没有,(5,100,100)有一些非零值作为开始,而(50,100,100)则全是零。这很好,因为np.empty从未承诺结果不会是零——我们只是测量了之前内存中存在的垃圾。如果我们够无聊,我想我们可以查看内存分配模式,但老实说,一旦我们知道它不能保证为零,我们就知道我们需要做什么了,其他的并不重要。 - DSM
1个回答

13

np.emptynp.zeros的功能不同。

np.empty从可用内存空间创建一个数组,将内存中存在的任何值留下作为该数组的值。 这些值可能是零也可能不是。

np.zeros从可用内存空间创建一个数组,并使用您选择的dtype填充它以零。显然,np.zeros需要做更多工作,因此速度应该更慢,因为它还要写入分配的内存。

更公平的比较应该在np.emptynp.ndarray之间进行。


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