假设我想对一个NumPy数组列表执行逐元素求和操作:
tosum = [rand(100,100) for n in range(10)]
我一直在寻找最好的方法来做这件事。看起来numpy.sum很糟糕:
timeit.timeit('sum(array(tosum), axis=0)',
setup='from numpy import sum; from __main__ import tosum, array',
number=10000)
75.02289700508118
timeit.timeit('sum(tosum, axis=0)',
setup='from numpy import sum; from __main__ import tosum',
number=10000)
78.99106407165527
Reduce的速度要快得多(几乎相当于两个数量级):
timeit.timeit('reduce(add,tosum)',
setup='from numpy import add; from __main__ import tosum',
number=10000)
1.131795883178711
看起来,使用reduce比非NumPy的sum有更明显的优势(请注意,这些是针对1e6次运行而不是上面时间的1e4次运行):
timeit.timeit('reduce(add,tosum)',
setup='from numpy import add; from __main__ import tosum',
number=1000000)
109.98814797401428
timeit.timeit('sum(tosum)',
setup='from __main__ import tosum',
number=1000000)
125.52461504936218
还有其他方法我应该尝试吗?有人可以解释一下排名吗?
编辑
如果列表先转换为numpy数组,则numpy.sum显然更快:
tosum2 = array(tosum)
timeit.timeit('sum(tosum2, axis=0)',
setup='from numpy import sum; from __main__ import tosum2',
number=10000)
1.1545608043670654
然而,我只有兴趣做一次求和,所以将数组转换为numpy数组仍会带来实际的性能惩罚。
np.sum
首先创建一个数组,然后对其求和,这可能解释了它的性能不佳... 我猜如果一开始就传递了一个np.ndarray
,那么它应该是最快的。 - mgilson