2013-06-27 21 views
6

Próbuję przepisać funkcję za pomocą numpy, która jest oryginalnie w MATLAB. Jest to logiczne część indeksujący, który przedstawia się następująco w MATLAB:Uzyskiwanie siatki macierzy poprzez indeksowanie logiczne w Numpy

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

ans = 

    1  4 
    13 16 

Kiedy próbuję to zrobić w numpy, nie mogę uzyskać prawidłowe indeksowanie:

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

Jaki jest właściwy sposób na uzyskanie siatka z macierzy poprzez indeksowanie logiczne?

+0

zawiadomień I że mogę to zrobić za pomocą 'X [idx,:] [:, idx]' ale nie jest to dziwne? – petrichor

Odpowiedz

7

Można również napisać:

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

+1; Nie wiedziałem o 'np.ix_'. Jednak to podejście ma gorszą wydajność (2x) niż "regularne indeksowanie". – root

+1

@root: różni się od twojego podejścia, ponieważ pozwala modyfikować plasterki macierzy, podczas gdy twój daje dostęp tylko do odczytu: http://wiki.scipy.org/NumPy_for_Matlab_Users#head-13d7391dd7e2c57d293809cff080260b46d8e664 – Amro

+0

To prawda. Możesz dodać to do swojej odpowiedzi. – root

2

W numpy nazywa się to fancy indexing. Aby uzyskać pożądane elementy, należy użyć tablicy indeksów 2D.

Możesz użyć outer, aby utworzyć z własnej tablicy właściwą tablicę indeksów. The outers, po zastosowaniu do dwóch sekwencji 1D, porównaj każdy element jednej sekwencji z każdym elementem drugiego. Przypominając, że True*True=True i False*True=False Z np.multiply.outer(), która jest taka sama jak np.outer(), może dać Ci 2D indeksach:

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) 

które można wykorzystać:

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

w normalnym kodu można użyć x=[np.outer(idx,idx)] ale nie oszczędza pamięci, działa tak samo, jak gdyby po wykonaniu plasterka dodano del idx_2D.

+2

Nie zapisujesz żadnej pamięci, nie przypisując tej tablicy pośredniej do zmiennej: zostanie ona utworzona, wykorzystana, a następnie odrzucona. Tak samo, jakby po indeksowaniu napisano 'del idx_2D'. – Jaime

+0

Dziękuję za komentarz, zaktualizuję odpowiedź! –

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 Nie wiedziałem, że przekształcenie listy 'ìdx' w tablicę umożliwi poprawne indeksowanie za pomocą' x [idx] ' –

Powiązane problemy