2013-08-16 15 views
6

In Python voglio trovare un modo veloce (senza ciclo for) per assegnare indici di array di riferimento. Questo è il risultato desiderato utilizzando un ciclo for:Assegnazione contemporanea di indici di array identici in Python/Numpy

import numpy as np 
a=np.arange(9, dtype=np.float64).reshape((3,3)) 
# The array indices: [2,3,4] are identical. 
Px = np.uint64(np.array([0,1,1,1,2])) 
Py = np.uint64(np.array([0,0,0,0,0])) 
# The array to be added at the array indices (may also contain random numbers). 
x = np.array([.1,.1,.1,.1,.1]) 

for m in np.arange(len(x)): 
    a[Px[m]][Py[m]] += x 

print a 
%[[ 0.1 1. 2.] 
%[ 3.3 4. 5.] 
%[ 6.1 7. 8.]] 

Quando provo ad aggiungere x-a gli indici Px,Py io, ovviamente, non si ottiene lo stesso risultato (3.3 vs 3.1):

a[Px,Py] += x 
print a 
%[[ 0.1 1. 2.] 
%[ 3.1 4. 5.] 
%[ 6.1 7. 8.]] 

C'è un modo per farlo con Numpy? Grazie.

+0

Prima di tutto, vorrei raggruppare i valori insieme, in modo da avere una lista di tuple (Px, Py). Di ordinare questo elenco, contare le occorrenze, moltiplicare x con quel numero e aggiungerlo all'array. Ma in qualche modo intorpidito sembra saltare i doppi ingressi .... strano. – Dschoni

risposta

7

Sì, si può fare, ma è un po 'difficile:

# convert yourmulti-dim indices to flat indices 
flat_idx = np.ravel_multi_index((Px, Py), dims=a.shape) 
# extract the unique indices and their position 
unique_idx, idx_idx = np.unique(flat_idx, return_inverse=True) 
# Aggregate the repeated indices 
deltas = np.bincount(idx_idx, weights=x) 
# Sum them to your array 
a.flat[unique_idx] += deltas 
+0

Bah, mi ha battuto con la stessa risposta esatta di 4 secondi. Anche se, speravo sinceramente che esistesse un modo migliore per farlo. – Daniel

+0

Grazie! Mi piace il modo in cui hai usato la funzione np.ravel_multi_index per ottenere gli indici flat e quindi utilizzare np.bincount con il parametro opzionale weights. – Paul

Problemi correlati