事实证明np.argmax
is速度快得惊人,但是only与本机 numpy 数组。对于国外的数据,几乎所有的时间都花在了转换上:
In [194]: print platform.architecture()
('64bit', 'WindowsPE')
In [5]: x = np.random.rand(10000)
In [57]: l=list(x)
In [123]: timeit numpy.argmax(x)
100000 loops, best of 3: 6.55 us per loop
In [122]: timeit numpy.argmax(l)
1000 loops, best of 3: 729 us per loop
In [134]: timeit numpy.array(l)
1000 loops, best of 3: 716 us per loop
我称你的函数“效率低下”,因为它首先将所有内容转换为列表,然后迭代它 2 次(实际上,3 次迭代 + 列表构造)。
我打算建议这样的事情,只迭代一次:
def imax(seq):
it=iter(seq)
im=0
try: m=it.next()
except StopIteration: raise ValueError("the sequence is empty")
for i,e in enumerate(it,start=1):
if e>m:
m=e
im=i
return im
但是,您的版本速度更快,因为它迭代了很多次,但使用的是 C 代码,而不是 Python 代码。 C 的速度要快得多 - 即使考虑到转换也花费了大量时间:
In [158]: timeit imax(x)
1000 loops, best of 3: 883 us per loop
In [159]: timeit fastest_argmax(x)
1000 loops, best of 3: 575 us per loop
In [174]: timeit list(x)
1000 loops, best of 3: 316 us per loop
In [175]: timeit max(l)
1000 loops, best of 3: 256 us per loop
In [181]: timeit l.index(0.99991619010758348) #the greatest number in my case, at index 92
100000 loops, best of 3: 2.69 us per loop
因此,进一步加快速度的关键知识是了解序列中的数据本身是什么格式(例如,是否可以省略转换步骤或使用/编写该格式本身的另一个功能)。
顺便说一句,您可能会通过使用获得一些加速aggregate(max_fn)
代替agg([max_fn])
.