Vieille question, mais je voudrais fournir ma propre solution qui s'avère être la plus rapide, utiliser la normale list
au lieu de np.array
la saisir (ou la transférer dans la liste en premier), sur la base de mon test au banc.
Vérifiez-le si vous le rencontrez également.
def count(a):
results = {}
for x in a:
if x not in results:
results[x] = 1
else:
results[x] += 1
return results
Par exemple,
>>>timeit count([1,1,1,2,2,2,5,25,1,1]) would return:
100000 boucles, le meilleur de 3: 2,26 µs par boucle
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]))
100000 boucles, le meilleur de 3: 8,8 µs par boucle
>>>timeit count(np.array([1,1,1,2,2,2,5,25,1,1]).tolist())
100000 boucles, meilleur de 3: 5,85 µs par boucle
Alors que la réponse acceptée serait plus lente, et la scipy.stats.itemfreq
solution est encore pire.
Un test plus approfondi n'a pas confirmé l'attente formulée.
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
Réf. commentaires ci-dessous sur le cache et autres effets secondaires en RAM qui influencent les résultats d'un test massivement répétitif d'un petit ensemble de données.
collections.Counter(x)
suffisant?