2013-06-04 6 views
5

Also, ich habe Listen von Wörtern und ich muss wissen, wie oft jedes Wort auf jeder Liste erscheint. Die Verwendung von ".count (word)" funktioniert, aber es ist zu langsam (jede Liste hat Tausende von Wörtern und ich habe Tausende von Listen).Kann ich numpy.histogram dazu bringen, sich wie numpy.bincount zu verhalten?

Ich habe versucht, Dinge mit numpy zu beschleunigen. Ich habe für jedes Wort einen eindeutigen Zahlencode generiert, so dass ich numpy.bincount verwenden konnte (da es nur mit Ganzzahlen, nicht mit Zeichenfolgen funktioniert). Aber ich bekomme "ValueError: Array ist zu groß".

Also jetzt versuche ich das "bins" -Argument der numpy.histogram-Funktion zu optimieren, damit es die Häufigkeitszählungen zurückgibt, die ich brauche (irgendwie scheint numpy.histogram keine Probleme mit großen Arrays zu haben). Aber bisher nicht gut. Irgendjemand da draußen hat das schon mal gemacht? Ist es überhaupt möglich? Gibt es eine einfachere Lösung, die ich nicht sehen kann?

+0

Wie groß ist Ihr Array? Ich habe gerade mit einem 10000000 Länge Array von Ints verwendet und es funktionierte gut. Ich habe keinen Speicher mehr, bevor ich den Fehler erhalte. –

+1

Ich denke, das Problem hier betrifft Ihr einzigartiges numerisches Codesystem, nicht die Größe der anfänglichen Arrays. np.bincount erstellt ein Array mit der Länge 1 + der größten Ganzzahl in Ihrem Array. Wenn Sie eine Art Codierung mit lächerlich hohen Zahlen verwenden, könnte dies zu einem Problem führen. Trotzdem hatte ich kein Problem mit np.bincount ([1000000000]). Was ist Ihr numerisches Kodierungsschema? – cge

+1

Ah scheint es, dass ein Fehler auftritt, wenn Sie Integer sind, die Sie versuchen, bin riesig. Sie können es emulieren mit 'foo = numpy.random.randint (2 ** 62, Größe = 1000); numpy.bincount (foo) '. Ich schätze, es versucht, ein riesiges, nicht indexierbares Array zu erstellen, um alle Bins zu speichern, und numpy sagt nein (dieser Fehler ist in 'multiarray/ctors.c'). Wie viele Wörter hast du? –

Antwort

5

Verwenden Sie nicht numpy für dieses. Verwenden Sie stattdessen collections.Counter. Es ist für diesen Anwendungsfall konzipiert.

+0

Dies ist eindeutig der richtige Weg, wenn das Problem wie beschrieben ist! –

+0

Super! Sauber und superschnell. – Parzival

4

Warum nicht Ihre ganze Zahlen auf den minimalen Satz reduzieren numpy.unique mit:

original_keys, lookup_vals = numpy.unique(big_int_string_array, return_inverse=True) 

können Sie dann benutzen Sie einfach numpy.bincount auf lookup_vals, und wenn Sie die ursprüngliche Zeichenfolge eindeutige Ganzzahl zurück zu bekommen, dann können Sie nur die Verwendung die Werte von lookup_vals als Indizes zu original_keys.

Also, so etwas wie:

import binascii 
import numpy 

string_list = ['a', 'b', 'c', 'a', 'b', 'd', 'c'] 
int_list = [binascii.crc32(string)**2 for string in string_list] 

original_keys, lookup_vals = numpy.unique(int_list, return_inverse=True) 

bins = bincount(lookup_vals) 

Auch vermeidet es die Notwendigkeit, Ihre Zahlen zu quadrieren.

1

Thiago, Sie können es auch direkt aus den kategorialen Variablen mit scipy itemfreq Methode versuchen. Hier ist ein Beispiel:

>>> import scipy as sp 
>>> import scipy.stats 
>>> rv = ['do', 're', 'do', 're', 'do', 'mi'] 
>>> note_frequency = sp.stats.itemfreq(rv) 
>>> note_frequency 
array([['do', '3'], 
     ['mi', '1'], 
     ['re', '2']], 
     dtype='|S2')