tuve este problema y, puesto que esta cuestión es de 5 años de edad, tuve que volver a hacer todos los puntos de referencia y cambiar la sintaxis de cuello de botella (no hay partsort
más, es partition
ahora).
Usé los mismos argumentos que kwgoodman, excepto el número de elementos recuperados, que aumenté a 50 (para ajustarse mejor a mi situación particular).
me dieron estos resultados:
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
Así, bottleneck_2 y numpy_2 (solución de ADAS) fueron atados. Pero, usando np.percentile
(numpy_2) tiene esos elementos topN ya ordenados, que no es el caso para las otras soluciones. Por otro lado, si también está interesado en los índices de esos elementos, el percentil no es útil.
Añadí pandas también, que usa cuello de botella debajo, si está disponible (http://pandas.pydata.org/pandas-docs/stable/install.html#recommended-dependencies).Si ya tiene una serie de pandas o un DataFrame para empezar, está en buenas manos, simplemente use nlargest
y listo.
El código utilizado para el punto de referencia es el siguiente (Python 3, por favor):
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))
duplicado posible de [Cómo llegar índices de valores máximos de N en una matriz numpy?] (Http: // stackoverflow .com/questions/6910641/how-to-get-index-of-n-maximum-values-in-a-numpy-array) – Seanny123