小智..
11
我有这个问题,因为这个问题是5年,我不得不重做所有的基准测试并改变瓶颈的语法(现在已经没有partsort了,partition现在已经是这样了).
我使用与kwgoodman相同的参数,除了检索的元素数量,我增加到50(为了更好地适应我的特定情况).
我得到了这些结果:
bottleneck 1: 01.12 ms per loop
bottleneck 2: 00.95 ms per loop
pandas : 01.65 ms per loop
heapq : 08.61 ms per loop
numpy : 12.37 ms per loop
numpy 2 : 00.95 ms per loop
因此,瓶颈_2和numpy_2(adas的解决方案)是并列的.但是,使用np.percentile(numpy_2)你已经排序了那些topN元素,而其他解决方案则不然.另一方面,如果您对这些元素的索引感兴趣,百分位数也没用.
我也添加了pandas,它使用了下面的瓶颈(如果有的话)(http://pandas.pydata.org/pandas-docs/stable/install.html#recommended-dependencies).如果你已经开始使用pandas系列或DataFrame,那么你就掌握得很好,只需使用nlargest就可以了.
用于基准测试的代码如下(请参阅python 3):
import time
import numpy as np
import bottleneck as bn
import pandas as pd
import heapq
def bottleneck_1(a, n):
return -bn.partition(-a, n)[:n]
def bottleneck_2(a, n):
return bn.partition(a, a.size-n)[-n:]
def numpy(a, n):
return a[a.argsort()[-n:]]
def numpy_2(a, n):
M = a.shape[0]
perc = (np.arange(M-n,M)+1.0)/M*100
return np.percentile(a,perc)
def pandas(a, n):
return pd.Series(a).nlargest(n)
def hpq(a, n):
return heapq.nlargest(n, a)
def do_nothing(a, n):
return a[:n]
def benchmark(func, size=1000000, ntimes=100, topn=50):
t1 = time.time()
for n in range(ntimes):
a = np.random.rand(size)
func(a, topn)
t2 = time.time()
ms_per_loop = 1000000 * (t2 - t1) / size
return ms_per_loop
t1 = benchmark(bottleneck_1)
t2 = benchmark(bottleneck_2)
t3 = benchmark(pandas)
t4 = benchmark(hpq)
t5 = benchmark(numpy)
t6 = benchmark(numpy_2)
t0 = benchmark(do_nothing)
print("bottleneck 1: {:05.2f} ms per loop".format(t1 - t0))
print("bottleneck 2: {:05.2f} ms per loop".format(t2 - t0))
print("pandas : {:05.2f} ms per loop".format(t3 - t0))
print("heapq : {:05.2f} ms per loop".format(t4 - t0))
print("numpy : {:05.2f} ms per loop".format(t5 - t0))
print("numpy 2 : {:05.2f} ms per loop".format(t6 - t0))