复制numpy数组的速度


问题内容

我想知道是否有使用b = np.array(a)而不是b = np.copy(a)将Numpy数组复制a到b中的缺点。当我时%timeit,前者可以提高100%。

在两种情况下b is a均为False,并且我可以操纵b保留a原样,因此我想这可以实现的期望.copy()

我有什么想念的吗?使用np.array复制数组有什么不当之处?

使用python 3.6.5,numpy 1.14.2时,对于较大的尺寸,速度差异会迅速缩小:

a = np.arange(1000)

%timeit np.array(a)
501 ns ± 30.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.copy(a)  
1.1 µs ± 35.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

问题答案:

来自以下文档numpy.copy

这等效于:

>>> np.array(a, copy=True)

另外,如果您查看源代码

def copy(a, order='K'):
    return array(a, order=order, copy=True)

一些时间:

In [1]: import numpy as np

In [2]: a = np.ascontiguousarray(np.random.randint(0, 20000, 1000))

In [3]: %timeit b = np.array(a)
562 ns ± 10.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit b = np.array(a, order='K', copy=True)
1.1 µs ± 10.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [5]: %timeit b = np.copy(a)
1.21 µs ± 9.28 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [6]: a = np.ascontiguousarray(np.random.randint(0, 20000, 1000000))

In [7]: %timeit b = np.array(a)
310 µs ± 6.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [8]: %timeit b = np.array(a, order='K', copy=True)
311 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [9]: %timeit b = np.copy(a)
313 µs ± 4.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [10]: print(np.__version__)
1.13.3

出乎意料的是,简单地将参数显式设置为其默认值会改变的执行速度np.array()。另一方面,也许仅处理这些显式参数会增加足够的执行时间,以使小型数组有所作为。确实,从的源代码numpy.array()可以看到,当提供关键字参数时,还有更多的检查和更多的处理正在执行,例如see
goto full_path。如果未设置关键字参数,则执行会一直跳到goto finish。这种开销(对关键字参数的额外处理)是您在小型阵列的计时中检测到的。对于较大的阵列,与复制阵列的实际时间相比,此开销微不足道。