2017-03-15 36 views

Odpowiedz

11
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).

+0

Ksiega.Z chęcią skopiuję - i - wkleję to, ale link do dokumentacji może być nadal przydatny. –

+0

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'). –

+0

Można również przeliterować, że 'b [np.index_exp [:] * k + np.index_exp [i]]', który jest prawdopodobnie nieco bardziej czytelny – Eric

3

Nie jestem pewien, czy to będzie działać dla k przyćmionym ale robi dla 2 dim

a.take(i,axis=k) 
+2

Ma to wadę tworzenia kopii zamiast widoku. – user2357112

+0

@ user2357112: Huh, to trochę zaskakujące – Eric

1

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,)] 
+2

dodatkowe plasterki po 'i' są niepotrzebne jeśli chodzi o numpy – Aaron

+0

@Aaron Dzięki, byłem nieświadomy! – user108471

0

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.

1

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.