【发布时间】:2014-01-05 14:00:27
【问题描述】:
假设我想对一个 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 总和有一个有意义的领先优势(请注意,这些是针对 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,这将是最快的开始。 -
我预计 reduce 会比
sum高出大约 1/11,因为它跳过了sum中隐含的0 + tosum[0]。 -
这是有道理的。我从一堆单独的数组开始,所以首先将它们变成一个 numpy 数组会导致与 sum 为我做同样的性能损失(因为我只做一次 sum)。
标签: python optimization numpy