如果您选择以下三种方法之一来初始化一个零的数组,您会选择哪一个?为什么?
my_arr_1 = np.full(size, 0)
Run Code Online (Sandbox Code Playgroud)
要么
my_arr_2 = np.zeros(size)
Run Code Online (Sandbox Code Playgroud)
要么
my_arr_3 = np.empty(size)
my_arr_3[:] = 0
Run Code Online (Sandbox Code Playgroud) 我被一个感兴趣的博客文章由Mike槎他比较需要两个函数的时间numpy.zeros((N,N))和numpy.empty((N,N))为N=200和N=1000。我使用%timeit魔法在 jupyter notebook 中运行了一个小循环。下面的图表给出的所需要的时间之比numpy.zero来numpy.empty。对于N=346,numpy.zero比 慢大约 125 倍numpy.empty。在N=361及以上,这两个功能所需的时间几乎相同。
后来,在 Twitter 上的讨论导致了这样的假设:要么numpy为小分配做一些特殊的事情以避免malloc调用,要么操作系统可能会主动将分配的内存页面清零。
造成这种差异的原因是什么N,而较大的所需时间几乎相等N?
通过启动堆溢出编辑:我可以重现它(这就是为什么我来到这里的第1名),这里有一个情节np.zeros和np.empty独立。该比率看起来像 GertVdE 的原始图:
在 Python 3.9.0 64 位、NumPy 1.19.2、Windows 10 Pro 2004 64 位上完成,使用此脚本生成数据:
from timeit import repeat
import numpy as np
funcs = np.zeros, np.empty
number = 10
index = …Run Code Online (Sandbox Code Playgroud) 我很好奇它真正np.empty代替了多少差异np.zeros,以及关于np.ones。我运行这个小脚本来测试创建一个大数组所需的时间:
import numpy as np
from timeit import timeit
N = 10_000_000
dtypes = [np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64,
np.float16, np.float32, np.float64]
rep= 100
print(f'{"DType":8s} {"Empty":>10s} {"Zeros":>10s} {"Ones":>10s}')
for dtype in dtypes:
name = dtype.__name__
time_empty = timeit(lambda: np.empty(N, dtype=dtype), number=rep) / rep
time_zeros = timeit(lambda: np.zeros(N, dtype=dtype), number=rep) / rep
time_ones = timeit(lambda: np.ones(N, dtype=dtype), number=rep) / rep
print(f'{name:8s} {time_empty:10.2e} {time_zeros:10.2e} {time_ones:10.2e}')
Run Code Online (Sandbox Code Playgroud)
并获得了下表结果:
import numpy as np
from timeit import …Run Code Online (Sandbox Code Playgroud)