首页 > 解决方案 > NumPy 数组计算时间问题

问题描述

对不起,如果这个问题有点太基本了。

我在学习 NumPy 并通过为什么 NumPy 数组这么快?NumPy 数组之所以快是因为两件事

  1. np.array() 由相同的 dtype 组成,因此获得了引用局部性的好处。

  2. 通过 uFunc 之类的东西可以进行矢量化操作。

因此,按理说计算速度应该是:

(带有 np 数组的 uFuncs)>(带有 np 数组的循环)>(带有列表的循环)。

但是,下面的代码显示速度实际上是,

(带有 np 数组的 uFuncs)>(带有列表的循环)>(带有 np 数组的循环)。

换句话说,尽管使用带有 np 数组的 uFUncs 是最快的,但带有列表的循环比带有 np 数组的循环要快。谁能解释为什么会这样?

预先感谢您的回答!

import numpy as np
np.random.seed(0)

arr=np.arange(1,1000)
arrlist=[]
for i in range(1,1000):
  arrlist.append(i)

#case0: list loop
def list_loop(values): #values: 1D array I want to take reciprocal of
  output=[]
  for i in range(len(values)):
    output.append(1.0/values[i])
  return output


#case1: np array loop
def nparray_loop(values): #values: 1D array I want to take reciprocal of
  output=np.empty(len(values))
  for i in range(len(values)):
    output[i]=1.0/values[i]
  return output

#case2: uFunc
def nparray_uFunc(values):
  return 1.0/values

print("list loop computation time:")
%timeit list_loop(arrlist)
print('\n')

print("np array loop computation time:")
%timeit nparray_loop(arr)
print('\n')

print("uFunc computation time:")
%timeit nparray_uFunc(arr)

输出:

list loop computation time:
185 µs ± 5.63 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)


np array loop computation time:
4.28 ms ± 402 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


uFunc computation time:
5.42 µs ± 1.23 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

标签: pythonarraysnumpyvectorization

解决方案


列表在内部表示为 Python 对象的向量。numpy 数组是一种复杂的数据结构,其中实际的数字数据以原始机器格式存储。

要在 python 列表上调用 Python 函数,Python 只需从列表中提取适当的元素并调用该函数。要在 numpy 数组上调用 Python 函数,Python 必须获取 numpy 数组的每个单独的原始元素并将其转换为适当的 Python 表示,然后调用 Python 函数。

Numpy 对于向量运算来说速度很快。如果您打算逐个元素地查看数据元素,那么效率会降低。


推荐阅读