2013-06-04 15 views
5

Mam więc listę słów i muszę wiedzieć, jak często każde słowo pojawia się na każdej liście. Używanie ".count (word)" działa, ale jest zbyt wolne (każda lista zawiera tysiące słów i mam tysiące list).Czy mogę oszukać numpy.histogram tak, aby zachowywał się jak numpy.bincount?

Próbowałem przyspieszyć działanie dzięki numpy. Wygenerowałem unikalny kod numeryczny dla każdego słowa, więc mógłbym użyć numpy.bincount (ponieważ działa tylko z liczbami całkowitymi, a nie łańcuchami). Ale otrzymuję "ValueError: array is too big".

Teraz próbuję zmodyfikować argument "bin" funkcji numpy.histogram, aby zwrócił mi potrzebne liczby częstotliwości (w jakiś sposób numpy.histogram wydaje się nie mieć problemów z dużymi tablicami). Ale jak dotąd nic dobrego. Czy zdarzyło się, że ktoś wcześniej to zrobił? Czy to możliwe? Czy istnieje jakieś prostsze rozwiązanie, którego nie widzę?

+0

Jak duża jest twoja tablica !? Właśnie użyłem bincounta z tablicą długości 10000000 długości i działało dobrze. Zabrakło mi pamięci, zanim dostanę błąd. –

+1

Myślę, że tutaj problem dotyczy unikalnego systemu kodów numerycznych, a nie rozmiaru początkowych tablic. np.bincount utworzy tablicę o długości równej 1 + największej liczbie całkowitej w twojej tablicy, która, jeśli używasz jakiegoś rodzaju kodowania z absurdalnie dużymi liczbami, może spowodować problem. Nadal nie miałem problemu z np.bincount ([1000000000]). Jaki jest twój numeryczny schemat kodowania? – cge

+1

Ah wydaje się, że błąd pojawia się, gdy jesteś liczb całkowitych, które próbujesz bin są ogromne. Możesz emulować go za pomocą 'foo = numpy.random.randint (2 ** 62, size = 1000); numpy.bincount (foo) '. Domyślam się, że próbuje stworzyć ogromną, nieindeksowalną tablicę do przechowywania wszystkich binów, a numpy mówi "nie" (ten błąd występuje w 'multiarray/ctors.c'). Ile masz słów? –

Odpowiedz

5

Do tego celu nie należy używać numpy. Zamiast tego użyj collections.Counter. Jest przeznaczony do tego przypadku użycia.

+0

To jest oczywiście właściwy sposób, aby zrobić to, jeśli problem jest taki, jak opisano! –

+0

Awesome! Czysto i superszybko. – Parzival

4

Dlaczego nie obniżyć całkowite do minimalnego zestawu za pomocą numpy.unique:

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

Następnie można po prostu użyć numpy.bincount na lookup_vals, a jeśli trzeba odzyskać oryginalny ciąg unikalną liczbę całkowitą, można po prostu użyć wartości lookup_vals jako wskaźniki do original_keys.

Tak, coś takiego:

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) 

Ponadto, pozwala na uniknięcie konieczności Square to Twój całkowitymi.

1

Thiago, Możesz również wypróbować go bezpośrednio ze zmiennych jakościowych za pomocą metody itemfreq scipy. Oto przykład:

>>> 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')