Mam-wymiarowej tablicy numpy, a ja chciałbym uzyskać i
-tynk z k
-ty wymiar. Tam musi być coś lepszego niżOtrzymaj i-ty kawałek k-tego wymiaru w tablicy numpy
# ...
elif k == 5:
b = a[:, :, :, :, :, i, ...]
# ...
Mam-wymiarowej tablicy numpy, a ja chciałbym uzyskać i
-tynk z k
-ty wymiar. Tam musi być coś lepszego niżOtrzymaj i-ty kawałek k-tego wymiaru w tablicy numpy
# ...
elif k == 5:
b = a[:, :, :, :, :, i, ...]
# ...
b = a[(slice(None),) * k + (i,)]
Construct krotki indeksowania ręcznie.
Jak udokumentowano w Python language reference wyrazem postaci
a[:, :, :, :, :, i]
przekształca się
a[(slice(None), slice(None), slice(None), slice(None), slice(None), i)]
Można osiągnąć ten sam efekt, że krotka budynku bezpośrednio zamiast notacji krojenia. (Jest to drobne zastrzeżenie, że budowanie krotki bezpośrednio produkuje a[(i,)]
zamiast a[i]
dla k=0
, ale NumPy obsługuje te same dla skalarnego i
).
Nie jestem pewien, czy to będzie działać dla k przyćmionym ale robi dla 2 dim
a.take(i,axis=k)
Ma to wadę tworzenia kopii zamiast widoku. – user2357112
@ user2357112: Huh, to trochę zaskakujące – Eric
Zasadniczo, chcesz być w stanie programowo utworzyć krotki :, :, :, :, :, i, ...
w celu przekazania go jako wskaźnik a
. Niestety, nie można po prostu użyć zwykłego multiplikowania krotki bezpośrednio na operatorze dwukropka (tj. (:,) * k
nie będzie działało, aby wygenerować krotkę operatorów okrężnicy k
). Można jednak uzyskać wystąpienie "przekroju okrężnicy" za pomocą colon = slice(None)
. Następnie można wykonać b = a[(colon,) * k + (i,)]
, który będzie skutecznie indeksować a
w kolumnie th i
wymiaru o rozmiarze .
Opakowanie to w zależności, można uzyskać:
def nDimSlice(a, k, i):
colon = slice(None)
return a[(colon,) * k + (i,)]
dodatkowe plasterki po 'i' są niepotrzebne jeśli chodzi o numpy – Aaron
@Aaron Dzięki, byłem nieświadomy! – user108471
Nie jestem pewien, czy to podejście spowodowałoby całą kopię tablicy *, ale wziąłbym plasterek transponowane macierz w celu uzyskania osi kt:
import numpy as np
def get_slice(arr, k, i):
if k >= arr.ndim: #we need at least k dimensions (0 indexed)
raise ValueError("arr is of lower dimension than {}".format(k))
axes_reorder = list(range(arr.ndim)) #order of axes for transpose
axes_reorder.remove(k) #remove original position of k
axes_reorder.insert(0,k) #insert k at beginning of order
return arr.transpose(axes_reorder)[i] #k is first axis now
Ma to również dodatkową zaletę łatwiejszego sprawdzania liczby wymiarów przed próbowaniem plasterka.
* zgodnie z docs, widok pamięci jest tworzony, gdy tylko jest to możliwe.
o to późne wejście, które mogą obsługiwać negatywne argumenty osi bez konieczności znajomości kształtu jej argumentu wcześniej:
def put_at(inds, axis=-1, slc=(slice(None),)):
return (axis<0)*(Ellipsis,) + axis*slc + (inds,) + (-1-axis)*slc
Aby być stosowany jako w
a[put_at(ind_list,axis=axis)]
ind_list
może być skalarne jak w twoim przypadku lub coś bardziej interesującego.
Skopiowano z this komentarz do mojej.
Ksiega.Z chęcią skopiuję - i - wkleję to, ale link do dokumentacji może być nadal przydatny. –
notacja plastra, np. 'a []' jest po prostu syntaktycznym cukrem dla wywołania '__getitem__' przekazując mu krotkę, w tym przypadku krotkę obiektów plasterka (notacja': 'jest syntaktycznym sugerem dla obiektu' slice'). –
Można również przeliterować, że 'b [np.index_exp [:] * k + np.index_exp [i]]', który jest prawdopodobnie nieco bardziej czytelny – Eric