2013-07-31 13 views
5

Zastanawiam się, czy ktoś wie, jak wektoryzować funkcję hashing w Pythonie. Na przykład, jest to mój kod:Hashowanie funkcji szumiących w pythonie

import numpy as np 
    hashlen = 5 
    x = np.array([4, 7, 4, 2, 6, 8, 0, 6, 3, 1]) 
    h = np.array([0, 3, 1, 2, 4, 2, 1, 0, 3, 1]) 

funkcją mieszaja, h oznacza indeksy nowego wektora ja mieszaja X do, czyli indeksu 0 wektora hashed powinien mieć 4 i 6 podsumować, indeks 1 powinien mieć 4, 0 i 1 podsumował, itd. Otrzymany mieszany wektorów powinny być:

w = np.array([ 10, 5, 10, 10, 6]) 

Jednym ze sposobów na to jest oczywiście poprzez zapętlenie poprzez indeksy hash, czyli:

for itr in range(hashlen): 
     w[itr] = np.sum(x[np.where(h==itr)]) 

W przypadku dużych wektorów złożoność jest funkcją hashlen (długość mieszanego wektora). Może to zająć zbyt dużo czasu, szczególnie w przypadku np.where().

chcę zrobić coś takiego:

w = np.zeros(hashlen) 
    w[h]+= x 

Jednak wynik ten jest taki sam jak robi

w = np.zeros(hashlen) 
    w[h] = x 

Czy ktoś może dać mi znać, jeśli mam coś tutaj brakuje? A może istnieje "łatwy" sposób na mieszanie funkcji, który nie wymaga zbyt wielu obliczeń?

Odpowiedz

5

Można użyć bincount z wagi do tego, co prosicie:

>>> np.bincount(h,weights=x) 
array([ 10., 5., 10., 10., 6.]) 

Dla matryc:

>>> import numpy as np 
>>> a=np.random.randint(0,5,(50,50)) 
>>> rand=np.random.rand(5) 
>>> rand 
array([ 0.10899745, 0.35296303, 0.21127571, 0.56433924, 0.27895281]) 
>>> b=np.take(rand,a) 

#Unfortunately you cannot do it like this: 
>>> np.bincount(a,weights=b) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: object too deep for desired array 

#There we go: 
>>> np.bincount(a.flat,weights=b.flat) 
array([ 55.04371257, 172.59892108, 96.34172236, 297.40677707, 
     145.89232039]) 

ten stosowany fantazyjne indeksowanie, aby zobaczyć, co się dzieje:

>>> np.bincount(a.flat) 
array([505, 489, 456, 527, 523]) 
>>> np.bincount(a.flat)*rand 
array([ 55.04371257, 172.59892108, 96.34172236, 297.40677707, 
     145.89232039]) 
+0

Dokładnie to, czego szukałem. Dzięki wielkie! –

+0

Po prostu ciekawy - czy można coś takiego zrobić na macierzach zamiast wektorach? Bez pętli oczywiście. –

+0

Zaktualizowano dla macierzy. Są inne sposoby, jeśli szukasz czegoś innego. – Daniel