Stare pytanie, ale chciałbym podać własne rozwiązanie, które okazuje się najszybsze, list
zamiast tego używaj normalnegonp.array
wejściowego (lub najpierw przenieś do listy), w oparciu o mój test laboratoryjny.
Sprawdź to, jeśli go spotkasz.
def count(a):
results = {}
for x in a:
if x not in results:
results[x] = 1
else:
results[x] += 1
return results
Na przykład,
>>>timeit count([1,1,1,2,2,2,5,25,1,1]) would return:
100000 pętli, najlepiej 3: 2,26 µs na pętlę
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]))
100000 pętli, najlepiej 3: 8,8 µs na pętlę
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]).tolist())
100000 pętli, najlepiej 3: 5,85 µs na pętlę
Chociaż przyjęta odpowiedź byłaby wolniejsza, a scipy.stats.itemfreq
rozwiązanie jest jeszcze gorsze.
Bardziej szczegółowe badanie nie potwierdziło sformułowanych oczekiwań.
from zmq import Stopwatch
aZmqSTOPWATCH = Stopwatch()
aDataSETasARRAY = ( 100 * abs( np.random.randn( 150000 ) ) ).astype( np.int )
aDataSETasLIST = aDataSETasARRAY.tolist()
import numba
@numba.jit
def numba_bincount( anObject ):
np.bincount( anObject )
return
aZmqSTOPWATCH.start();np.bincount( aDataSETasARRAY );aZmqSTOPWATCH.stop()
14328L
aZmqSTOPWATCH.start();numba_bincount( aDataSETasARRAY );aZmqSTOPWATCH.stop()
592L
aZmqSTOPWATCH.start();count( aDataSETasLIST );aZmqSTOPWATCH.stop()
148609L
Nr ref. komentarze poniżej dotyczące pamięci podręcznej i innych skutków ubocznych w pamięci RAM, które wpływają na mały zestaw danych masowo powtarzających się wyników testów.
collections.Counter(x)
wystarczający?