2015-02-13 10 views
6

Perché non è possibile indicizzare un array ND utilizzando un elenco di indici di tuple in questo modo?Indicizzazione di una matrice numpy con un elenco di tuple

idx = [(x1, y1), ... (xn, yn)] 
X[idx] 

Invece devo fare qualcosa di ingombrante come

idx2 = numpy.array(idx) 
X[idx2[:, 0], idx2[:, 1]] # or more generally: 
X[tuple(numpy.vsplit(idx2.T, 1)[0])] 

C'è un modo più divinatorio più semplice?

risposta

13

È possibile utilizzare un elenco di tuple, ma la convenzione è diversa da quella che si desidera. numpy prevede un elenco di indici di riga, seguito da un elenco di valori di colonna. A quanto pare, vuoi specificare un elenco di coppie (x, y).

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing La sezione pertinente nella documentazione è "indice di array intero".


Ecco un esempio, cercando 3 punti in un array 2D. (2 punti in 2D può essere fonte di confusione):

In [223]: idx 
Out[223]: [(0, 1, 1), (2, 3, 0)] 
In [224]: X[idx] 
Out[224]: array([2, 7, 4]) 

Usando il vostro stile di coppie xy degli indici:

In [230]: idx1 = [(0,2),(1,3),(1,0)] 
In [231]: [X[i] for i in idx1] 
Out[231]: [2, 7, 4] 

In [240]: X[tuple(np.array(idx1).T)] 
Out[240]: array([2, 7, 4]) 

X[tuple(zip(*idx1))] è un altro modo di fare la conversione. tuple() è facoltativo in Python2. zip(*...) è un linguaggio Python che inverte l'annidamento di un elenco di elenchi.

Siete sulla strada giusta con:

In [242]: idx2=np.array(idx1) 
In [243]: X[idx2[:,0], idx2[:,1]] 
Out[243]: array([2, 7, 4]) 

mio tuple() è solo un po 'più compatto (e non necessariamente più 'divinatorio'). Data la convenzione numpy, è necessaria una sorta di conversione.

(Dovremmo controllare cosa funziona con n-dimensioni e m-punti?)