2013-07-31 4 views
5

Mi chiedo se qualcuno sa come vettorializzare l'hashing delle funzionalità in Python. Ad esempio, questo è il mio codice:Vettorizzazione dell'hash di feature in python

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

In funzione hash h rappresenta gli indici del nuovo vettore sto hashing x a, cioè l'indice 0 del vettore hash dovrebbe avere 4 e 6 riassumere, Indice 1 dovrebbe avere 4, 0 e 1 riassumere, ecc Il vettore hash risultante dovrebbe essere:

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

Un modo per fare questo è naturalmente dal ciclo attraverso gli indici hash, cioè:

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

Per i vettori di grandi dimensioni, la complessità è una funzione di hashlen (la lunghezza del vettore hash). Potrebbe richiedere troppo tempo, specialmente con un np.where() in esso.

voglio fare qualcosa di simile:

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

Tuttavia, il risultato di questo è lo stesso di fare

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

Qualcuno può farmi sapere se mi manca qualcosa qui? O se c'è un modo "facile" di fare l'hashing delle caratteristiche che non comporta troppi calcoli?

risposta

5

È possibile utilizzare bincount con i pesi per fare ciò che si sta chiedendo:

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

Per matrici:

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

Questa indicizzazione di fantasia usato per vedere che cosa stava accadendo:

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

Esattamente quello che stavo cercando. Grazie mille! –

+0

Solo curioso - è possibile fare qualcosa del genere su matrici anziché su vettori? Senza looping ovviamente. –

+0

Aggiornato per matrici. Ci sono altri modi se stai cercando qualcos'altro. – Daniel