我有一个代码,其中我对一堆是多个数组的数字数据进行了许多基本的算术计算。我已经意识到,在大多数可想象的操作中,numpy类始终比默认的python慢。为什么会这样?
例如,我有一个简单的代码片段,其中我所做的只是用另一个numpy数组中检索的另一个更新1 numpy数组元素,或者用其他2个numpy数组元素的数学乘积更新了它。这应该是一项基本操作,但始终比我用list
进行时至少慢2-3倍。
首先,我认为这是因为我尚未统一数据结构,并且编译器必须进行许多不必要的转换。因此,我重新编码了整个内容,并用float
替换了每个numpy.float64
,并用list
替换了每个numpy.ndarray
,整个代码中的整个数据都是numpy.float64
,所以不必进行任何不必要的转换。
与我仅使用list
和float
相比,该代码仍然慢2-3倍。
例如:
ALPHA = [[random.uniform(*a_param) for k in range(l2)] for l in range(l1)]
COEFF = [[random.uniform(*c_param) for k in range(l2)] for l in range(l1)]
summa=0.0
for l in range(l1):
for k in range(l2):
summa+=COEFF[l][k] * ALPHA[l][k]
始终比以下速度快2-3倍:
ALPHA = numpy.random.uniform(*a_param, (l1,l2))
COEFF = numpy.random.uniform(*c_param, (l1,l2))
summa=0.0
for l in range(l1):
for k in range(l2):
summa+=COEFF[l][k] * ALPHA[l][k]
这是怎么可能的,我做错了什么吗,因为numpy应该可以加快速度。
我正在使用Python 3.5.3
和numpy (1.12.1)
作记录,我应该更新吗?
答案 0 :(得分:1)
修改NumPy数组的单个元素预计不会比修改Python列表的单个元素更快。当您在整个数组(或数组的子集)上执行“向量化”操作时,使用NumPy的速度就会加快。尝试将NumPy数组的前10000个元素分配为与另一个数组的前10000个元素相等,然后与使用列表进行比较。
如果您的数据和/或操作非常小(一个或几个元素),那么最好不使用NumPy。
答案 1 :(得分:0)
我尝试了两件事:
这是我的功能:
import numpy as np
def with_lists(l1, l2):
ALPHA = [[random.uniform(0, 1) for k in range(l2)] for l in range(l1)]
COEFF = [[random.uniform(0, 1) for k in range(l2)] for l in range(l1)]
summa=0.0
for l in range(l1):
for k in range(l2):
summa+=COEFF[l][k] * ALPHA[l][k]
return summa
def with_arrays(l1, l2):
ALPHA = np.random.uniform(size=(l1,l2))
COEFF = np.random.uniform(size=(l1,l2))
summa=0.0
for l in range(l1):
for k in range(l2):
summa+=COEFF[l][k] * ALPHA[l][k]
return summa
def with_ufunc(l1, l2):
"""Avoid the loop completely by exploitng numpy's
elementwise math."""
ALPHA = np.random.uniform(size=(l1,l2))
COEFF = np.random.uniform(size=(l1,l2))
return np.sum(COEFF * ALPHA)
当我比较速度(我在IPython中使用%timeit
魔术)时,得到以下信息:
>>> %timeit with_lists(10, 10)
107 µs ± 4.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit with_arrays(10, 10)
91.9 µs ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit with_ufunc(10, 10)
12.6 µs ± 589 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
第三个函数(无循环)在我的计算机上的速度大约是10到30倍,具体取决于l1
和l2
的值。