2013-06-27 4 views
6

Sto tentando di riscrivere una funzione usando numpy che è originariamente in MATLAB. C'è una parte logica di indicizzazione che è la seguente in MATLAB:Ottenere una griglia di una matrice tramite l'indicizzazione logica in Numpy

X = reshape(1:16, 4, 4).'; 
idx = [true, false, false, true]; 
X(idx, idx) 

ans = 

    1  4 
    13 16 

Quando provo a fare in NumPy, non riesco a ottenere la corretta indicizzazione:

X = np.arange(1, 17).reshape(4, 4) 
idx = [True, False, False, True] 
X[idx, idx] 
# Output: array([6, 1, 1, 6]) 

Qual è il modo corretto di ottenere una griglia dalla matrice tramite indicizzazione logica?

+0

I bandi che posso farlo tramite 'X [idx,:] [:, idx]', ma non è poi così strano? – petrichor

risposta

7

Si potrebbe anche scrivere:

>>> X[np.ix_(idx,idx)] 
array([[ 1, 4], 
     [13, 16]]) 
+0

+1; Non sapevo su 'np.ix_'. Tuttavia, questo approccio ha prestazioni peggiori (2x) di "indicizzazione regolare". – root

+1

@root: questo è diverso dal tuo approccio poiché consente di modificare la matrice affettata, mentre la tua fornisce accesso di sola lettura: http://wiki.scipy.org/NumPy_for_Matlab_Users#head-13d7391dd7e2c57d293809cff080260b46d8e664 – Amro

+0

Vero, vero. Puoi aggiungerlo alla tua risposta. – root

2

In numpy questo è chiamato fancy indexing. Per ottenere gli elementi desiderati, è necessario utilizzare un array di indici 2D.

È possibile utilizzare un outer per creare dal proprio idx un numero corretto di indici 2D. The outers, quando applicato a due sequenze 1D, confronta ciascun elemento di una sequenza con ciascun elemento dell'altro. Ricordando che True*True=True e False*True=False, il np.multiply.outer(), che è la stessa di np.outer(), può darvi la 2D indici:

idx_2D = np.outer(idx,idx) 
#array([[ True, False, False, True], 
#  [False, False, False, False], 
#  [False, False, False, False], 
#  [ True, False, False, True]], dtype=bool) 

che è possibile utilizzare:

x[ idx_2D ] 
array([ 1, 4, 13, 16]) 

Nel codice reale è possibile utilizzare x=[np.outer(idx,idx)] ma non salva la memoria, funziona come se avessi incluso uno del idx_2D dopo aver eseguito la sezione.

+2

Non si salva alcuna memoria non assegnando quella matrice intermedia a una variabile: essa viene creata, utilizzata e quindi scartata. Lo stesso come se scrivessi un 'del idx_2D' dopo l'indicizzazione. – Jaime

+0

Grazie per il tuo commento, aggiornerò la risposta! –

4
In [1]: X = np.arange(1, 17).reshape(4, 4) 

In [2]: idx = np.array([True, False, False, True]) # note that here idx has to 
                # be an array (not a list) 
                # or boolean values will be 
                # interpreted as integers 

In [3]: X[idx][:,idx] 
Out[3]: 
array([[ 1, 4], 
     [13, 16]]) 
+0

+1 Non sapevo che la trasformazione della lista "ddx' in una matrice avrebbe consentito l'indicizzazione corretta usando' x [idx] ' –