【问题标题】:How come a numpy array created from list can be 10x faster than that from np.zeros for incrementation?为什么从 list 创建的 numpy 数组的增量可以比从 np.zeros 快 10 倍?
【发布时间】:2021-04-16 05:27:44
【问题描述】:

我正在使用 python 3.8 和 numpy 1.17.4。 下面这段代码的输出

import time
import sys
import numpy as np

if __name__ == '__main__':
  li = np.zeros(5000000,dtype=int)
  sys.stdout.write("%s %s\n" % (type(li),type(li[0])))
  start = time.process_time()
  li += 5
  sys.stdout.write("%.6fs\n" % (time.process_time()-start))
  li = np.zeros(5000000,dtype=int)
  li = list(li)
  li = np.array(li)
  sys.stdout.write("%s %s\n" % (type(li),type(li[0])))
  start = time.process_time()
  li += 5
  sys.stdout.write("%.6fs\n" % (time.process_time()-start))

看起来像

<class 'numpy.ndarray'> <class 'numpy.int64'>
0.037046s
<class 'numpy.ndarray'> <class 'numpy.int64'>
0.003537s

为什么后者的增量要快 10 倍?

【问题讨论】:

    标签: python python-3.x numpy


    【解决方案1】:

    在我看来解释和here一样。 事实上, numpy.zeros() 似乎是一个“懒惰”的操作。我对您的示例进行了两次修改:

    1. 我删除了在第二个度量之前暗示列表的两个语句 => 这两个度量变得相同
    2. 我添加了一个虚拟操作以强制 numpy.zero() 真正分配内存 => 这两个措施再次变得不同:
    import time
    import sys
    import numpy as np
    
    if __name__ == '__main__':
      li = np.zeros(5000000,dtype=int)
      sys.stdout.write("%s %s\n" % (type(li),type(li[0])))
      start = time.process_time()
      li += 5
      sys.stdout.write("%.6fs\n" % (time.process_time()-start))
      li = np.zeros(5000000,dtype=int)
      li += 0 #dummy operation 
      sys.stdout.write("%s %s\n" % (type(li),type(li[0])))
      start = time.process_time()
      li += 5
      sys.stdout.write("%.6fs\n" % (time.process_time()-start))
    

    【讨论】:

      【解决方案2】:

      您的时间估计可能不准确。它使用可能受其他因素影响的命令的单次迭代。使用%timeit 显示出更一致的结果,即使第二种方法具有更高的标准偏差。

      第一种方法:

      li = np.zeros(5000000,dtype=int)
      
      %timeit zi = li + 5
      12 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      第二种方法:

      li = np.zeros(5000000,dtype=int)
      li = list(li)
      li = np.array(li)
      
      %timeit zi = li + 5
      13.3 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      【讨论】:

      • 我编写了 itmeit.repeat 版本的代码。对于 100 次重复,它仍然显示快 10 倍。 timelist = timeit.repeat(stmt="li+=5",setup="import numpy as np;li=np.zeros(5000000,dtype=int)",number=1,repeat=100)timelist = timeit.repeat(stmt="li+=5",setup="import numpy as np;li=np.zeros(5000000,dtype=int);li=list(li);li=np.array(li)",number=1,repeat=100)
      猜你喜欢
      • 2019-04-05
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      相关资源
      最近更新 更多