2012-08-24 18 views
22

Chciałbym wyciąć tablicę numpy, aby uzyskać i-ten indeks w ostatnim wymiarze. Na tablicy 3D, będzie to:Plaster Numpy o dowolnych wymiarach

slice = myarray[:,:,i] 

Ale piszę funkcję gdzie mogę podjąć szereg dowolnych wymiarach, więc na tablicy 4D że muszę myarray[:,:,:,i], i tak dalej. Czy istnieje sposób, w jaki mogę uzyskać ten wycinek dla dowolnej tablicy bez wyraźnego zapisu wymiarów tablicy?

Odpowiedz

35

Jest ... lub Ellipsis, który robi dokładnie to:

slice = myarray[...,i] 

Wielokropek jest obiekt Pythona, gdyby chcesz używać go na zewnątrz kwadratowej notacji zamka.

+0

Dziękuję, nie wiedziałem o tym. Moja własna odpowiedź pozwala na bardziej ogólne plasterki, ale twoja jest naprawdę fajna. – tiago

+0

@tiago Rzeczywiście zawsze możesz zbudować krotkę krojącą. > Można tam też użyć 'Ellipsis' ... – seberg

5

Właściwie znalazłem odpowiedź. Jak podano w numpy's documentation, można to zrobić za pomocą obiektu slice. W moim przypadku byłoby to zrobić:

idx = [slice(None)] * (myarray.ndim - 1) + [i] 
my_slice = myarray[idx] 

slice(None) jest równoważne wybraniu wszystkich elementów tego indeksu, a ostatni [i] wybiera konkretny indeks ostatniego wymiaru.

+0

Chciałem to zasugerować, ale w rzeczywistości podejście Sebastiana jest znacznie bardziej eleganckie! Ponadto, nie sądzę, że twój kod faktycznie działa, mnożysz listę przez krotkę, a następnie łączę się z nagim indeksem bez obiektu 'slice()'. Może miałeś na myśli '[slice (None)] * myarray.shape [-1] + [slice (None, i)]' –

+1

@NiklasB. Ostatnie '[i]' jest poprawne, ale pierwsza część musi być '(myarray.ndim - 1)' dla mnożnika, jeśli 'Ellipsis' nie jest używany. – seberg

+0

@Sebastian, masz rację, testowałem używając numeru, a następnie zapomniałem umieścić len (myarray.shape [: - 1]). Po prostu naprawiłem to twoją sugestią. – tiago

2

chodzi o krojenie dowolny wymiar, poprzednie doskonałe odpowiedzi może zostać przedłużony do:

indx = [Ellipsis]*myarray.ndim 
indx[slice_dim] = i 
slice = myarray[indx] 

ta zwraca kawałek z dowolnego wymiaru slice_dim - slice_dim = -1 odtwarza poprzednie odpowiedzi. Dla kompletności - pierwsze dwie linie powyższym wykazie mogą być skondensowane do:

indx = [Ellipsis]*(slice_dim) + [i] + [Ellipsis]*(myarray.ndim-slice_dim-1) 

chociaż uważam, że poprzednia wersja bardziej czytelny.

Powiązane problemy