【问题标题】:What is the preferred way to preallocate NumPy arrays?预分配 NumPy 数组的首选方法是什么?
【发布时间】:2010-08-16 09:02:48
【问题描述】:

我是 NumPy/SciPy 的新手。从文档来看,预分配似乎更有效 单个数组而不是调用追加/插入/连接。

例如,要将一列 1 添加到数组中,我认为:

ar0 = np.linspace(10, 20, 16).reshape(4, 4)
ar0[:,-1] = np.ones_like(ar0[:,0])

比这个更喜欢:

ar0 = np.linspace(10, 20, 12).reshape(4, 3)
ar0 = np.insert(ar0, ar0.shape[1], np.ones_like(ar0[:,0]), axis=1)

我的第一个问题是这是否正确(第一个更好),我的第二个问题是,目前,我只是像这样预先分配我的数组(我在 SciPy 上的几个 Cookbook 示例中注意到了这一点网站):

np.zeros((8,5))

“NumPy 首选”的方法是什么?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    在性能很重要的情况下,np.emptynp.zeros 似乎是初始化 numpy 数组的最快方法。

    以下是每种方法和其他几种方法的测试结果。值以秒为单位。

    >>> timeit("np.empty(1000000)",number=1000, globals=globals())
    0.033749611208094166
    
    >>> timeit("np.zeros(1000000)",number=1000, globals=globals())
    0.03421245135849915
    
    >>> timeit("np.arange(0,1000000,1)",number=1000, globals=globals())
    1.2212416112155324
    
    >>> timeit("np.ones(1000000)",number=1000, globals=globals())
    2.2877375495381145
    
    >>> timeit("np.linspace(0,1000000,1000000)",number=1000, globals=globals())
    3.0824269766860652
    

    【讨论】:

      【解决方案2】:

      预分配会在一次调用中分配您需要的所有内存,而调整数组大小(通过调用追加、插入、连接或调整大小)可能需要将数组复制到更大的内存块。所以你是对的,预分配优先于(并且应该比)调整大小。

      根据您要创建的内容,有许多“首选”方法可以预分配 numpy 数组。有 np.zerosnp.onesnp.emptynp.zeros_likenp.ones_likenp.empty_like,以及许多其他创建有用数组的方法,例如 np.linspacenp.arange

      所以

      ar0 = np.linspace(10, 20, 16).reshape(4, 4)
      

      如果这最接近您想要的 ar0 就好了。

      但是,要使最后一列全为 1,我认为首选的方法是直接说

      ar0[:,-1]=1
      

      由于ar0[:,-1]的形状是(4,),所以1是broadcasted来匹配这个形状。

      【讨论】:

      • 日期时间数组呢?你上面建议的一次似乎都不起作用。 my_array= numpy.empty(10, dtype=numpy.datetime64) 之类的也不行。谢谢
      【解决方案3】:

      根据我的经验,numpy.empty() 是预分配 HUGE 数组的最快方式。我正在谈论的数组具有(80,80,300000) 和dtype uint8 的形状。

      代码如下:

      %timeit  np.empty((80,80,300000),dtype='uint8')
      %timeit  np.zeros((80,80,300000),dtype='uint8')
      %timeit  np.ones((80,80,300000),dtype='uint8')
      

      以及时间的结果:

      10000 loops, best of 3: 83.7 µs per loop  #Too much faster
      1 loop, best of 3: 273 ms per loop
      1 loop, best of 3: 272 ms per loop
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        • 2010-09-23
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多