复制numpy数组的速度

时间:2018-06-12 20:15:39

标签: python arrays 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)

3 个答案:

答案 0 :(得分:5)

来自numpy.copy的文档:

  

这相当于:

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

另外,如果你看一下source code

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()的执行速度。另一方面,也许只是处理这些显式参数会增加足够的执行时间来为小数组做出改变。实际上,从source code for the numpy.array()可以看出,当提供关键字参数时,还会执行更多检查和更多处理,例如,请参阅goto full_path。如果未设置关键字参数,则执行会一直跳至goto finish。这种开销(关键字参数的附加处理)是您在小数组的时序中检测到的。对于较大的阵列,与复制阵列的实际时间相比,这种开销是微不足道的。

答案 1 :(得分:1)

"使用np.array复制数组有什么不妥?"

我认为阅读起来比较困难。例如,array制作副本并不明显,但类似的asarray如果不必复制,则不会制作副本。读者基本上必须知道copy关键字参数的默认值才能确定。

答案 2 :(得分:0)

正如AGN指出的那样,np.array比np.copy更快,因为基本上后者是前者的包装器。这意味着python“失去”一些额外的时间来搜索这两个函数。装饰者也会发生类似的事情。

这个额外的时间对于实际目的来说是微不足道的,并且您获得了更好的代码可读性。

你可以使用一个大数组(数组创建需要主时间)来测试它,你会发现两者的%timeit差异很小。