Mam zmienną x, która ma kształt (2,2,50,100).
Mam też tablicę y, która jest równa np. Tablica ([0,10,20]). Dziwna rzecz dzieje się, gdy indeksuję x [0,:,:, y].
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
Dlaczego ostatnie wyjście (3,2,50), a nie (2,50,3)?
Odpowiedzi:
W ten sposób numpy wykorzystuje zaawansowane indeksowanie do rozgłaszania kształtów tablic. Kiedy zdasz a
0
dla pierwszego indeksu iy
dla ostatniego indeksu, numpy wyemituje0
ten sam kształt coy
. Zachodzi równoważność:x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. Oto przykładTeraz, ponieważ skutecznie przekazujesz dwa zestawy indeksów, używasz zaawansowanego interfejsu API indeksowania do tworzenia (w tym przypadku) par indeksów.
Który ma pierwszy wymiar taki sam jak długość
y
. Oto co widzisz.Jako przykład spójrz na tablicę z 4 wymiarami opisanymi w następnym fragmencie:
x
ma naprawdę łatwą do zrozumienia sekwencyjną formę, której możemy teraz użyć do pokazania, co się dzieje ...Pierwszy wymiar przypomina 2 skoroszyty programu Excel, drugi wymiar ma 3 arkusze w każdym skoroszycie, trzeci wymiar ma 4 wiersze na arkusz, a ostatni wymiar to 5 wartości dla każdego wiersza (lub kolumn na arkusz).
Patrząc na to w ten sposób, prosząc
x[0,:,:,0]
, jest powiedzenie: „w pierwszym skoroszycie, dla każdego arkusza, dla każdego wiersza, podaj mi pierwszą wartość / kolumnę”.Ale teraz dzięki zaawansowanemu indeksowaniu możemy myśleć o tym,
x[(0,0,0),:,:,y]
że „w pierwszym skoroszycie, dla każdego arkusza, dla każdego wiersza podaj miy
wartość th / kolumnę. Ok, teraz zrób to dla każdej wartościy
„To, że wariuje, to to, że numpy będzie nadawać, aby pasowało do zewnętrznych wymiarów tablicy indeksów. Więc jeśli chcesz wykonać tę samą operację jak powyżej, ale ZARÓWNO dla „skoroszytów programu Excel”, nie musisz zapętlać i łączyć. Możesz po prostu przekazać tablicę do pierwszego wymiaru, ale MUSI mieć zgodny kształt.
Przekazywanie liczby całkowitej zostaje przekazane do
y.shape == (3,)
. Jeśli chcesz przekazać tablicę jako pierwszy indeks, tylko ostatni wymiar tablicy musi być zgodnyy.shape
. To znaczy ostatni wymiar pierwszego indeksu musi wynosić 3 lub 1.Znaleziono krótkie wyjaśnienie w dokumentacji: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
Edytować:
Z pierwotnego pytania, aby uzyskać linijkę żądanego subplikowania, możesz użyć
x[0][:,:,y]
:Jeśli jednak próbujesz przypisać do tych podsieci, musisz bardzo uważać, patrząc na widok pamięci współdzielonej oryginalnej tablicy. W przeciwnym razie przypisanie nie będzie do oryginalnej tablicy, ale do kopii.
Pamięć współdzielona występuje tylko wtedy, gdy używasz liczby całkowitej lub wycinka do podzestawu tablicy, tj .
x[:,0:3,:,:]
Lubx[0,:,:,1:-1]
.Zarówno w twoim pierwotnym pytaniu, jak i moim przykładzie,
y
nie jest ani int, ani plasterek, więc zawsze kończy się przypisaniem do kopii oryginału.ALE! Ze względu na swoją tablicę
y
można wyrazić jako plaster, ty CAN rzeczywiście uzyskać przypisywany widok macierzy poprzez:Tutaj używamy wycinka,
0:21:10
aby pobrać każdy indeks, który byłby w środkurange(0,21,10)
. Musimy użyć,21
a nie20
dlatego, że punkt zatrzymania jest wykluczony z wycinka, tak jak wrange
funkcji.Zasadniczo, jeśli możesz skonstruować plasterek, który pasuje do twoich kryteriów subplikowania, możesz wykonać przypisanie.
źródło
To się nazywa
combining advanced and basic indexing
. Wcombining advanced and basic indexing
, numpy wykonaj najpierw indeksowanie w indeksowaniu zaawansowanym i podprzestrzeń / połącz wynik z wymiarem indeksowania podstawowego.Przykład z dokumentów:
tak, na
x[0,:,:,y]
,0
iy
są zaliczki indeksowania. Są one emitowane razem, aby uzyskać wymiar(3,)
.Ten
(3,)
pinezki do początku 2. i 3. Aby dokonać wymiaru(3, 2, 50)
Aby zobaczyć, że 1 i ostatni wymiar są naprawdę nadawania razem, można spróbować zmienić
0
aby[0,1]
zobaczyć błędu nadawaniaźródło