2012-03-20 16 views
11

La mia domanda riguarda un'operazione di array specifica che desidero esprimere utilizzando numpy.Numpy che accumula un array in un altro utilizzando l'array di indici

ho un array di carri w e una serie di indici idx della stessa lunghezza w e voglio riassumere tutti w con lo stesso valore idx e raccoglierli in un array v. come un ciclo, questo si presenta così:

for i, x in enumerate(w): 
    v[idx[i]] += x 

C'è un modo per fare questo con le operazioni di matrice? La mia ipotesi era v[idx] += w ma questo non funziona, dal momento che idx contiene lo stesso indice più volte.

Grazie!

+0

E * atomic * è davvero una descrizione inappropriata per quello che vuoi fare. – Constantinius

+0

Come lo descriveresti? Spero che il nuovo titolo sia migliore. –

+1

@Constantinius, ha accettato una risposta per tutte tranne una delle domande che ha posto, che ha avuto una risposta che, pur essendo buona, non ha affrontato il suo problema reale. Forse * dovresti lavorare su non attirare l'attenzione sull'aspetto del gioco di questo sito. –

risposta

15

numpy.bincount è stato introdotto per questo scopo:

tmp = np.bincount(idx, w) 
v[:len(tmp)] += tmp 

penso al 1.6 si può anche passare un minlength a bincount.

+0

Ero a conoscenza di bincount ma non sapevo che potesse gestire i pesi! fantastico :) –

+0

fico, quasi dimentica questo piccolo elfo. – nye17

+0

Sentiti libero di sentirti il ​​mio eroe per il resto della giornata :) –

4

Questo è un comportamento noto e, sebbene in qualche modo sfortunato, non presenta una soluzione alternativa a livello di disturbo. (bincount può essere usato per questo se si torce il suo braccio.) Fare il ciclo te stesso è davvero la soluzione migliore.

Nota che il codice avrebbe potuto essere un po 'più chiaro, senza ri-utilizzando il nome w e senza introdurre un'altra serie di indici, come

for i, w_thing in zip(idx, w): 
    v[i] += w_thing 

Se avete bisogno di accelerare questo ciclo, si potrebbe avere passare a C. Cython rende questo relativamente facile.

+0

Ancora più semplice: 'for i in idx: v [i] + = w [i]'. –

+1

Oppure l'eccellente 'scipy.weave.inline'. – katrielalex

+0

Senza indici questo dovrebbe funzionare, giusto? Il codice che hai postato semplicemente '' v + w'', giusto? (Se '' v'' è più lungo di '' w'' vengono usati solo i primi elementi '' len (w) '' Riutilizzare '' w'' era un errore di battitura piuttosto male, mi dispiace –

Problemi correlati