2012-11-23 9 views
5

NumPy tablicy przyznaje listę wskaźników, na przykładMultiple plaster w liście do indeksowania tablicy numpy

a = np.arange(1000) 
l = list([1,44,66,33,90,345]) 
a[l] = 22 

Ale ta metoda nie działa, jeśli chcemy korzystać z wielu plasterek indeksowanie lub indeksy plus plasterek, na przykład.

a = np.arange(1000) 
l = list([1,44,66,33,90, slice(200,300) , slice(500,600) ]) 
a[l] = 22 

Ten kod zwraca komunikat o błędzie:

IndexError: too many indices 

moje pytanie jest bardzo prosta: wiesz, jeśli w numpy lub scipy istnieją skutecznego sposobu korzystania z tego rodzaju indeksowanie?

Co to jest dobry i skuteczny sposób używania takiej metody indeksowania?

Nie zapominaj, że użycie plasterków daje bardzo szybki kod; a moim problemem jest mieć tak szybki jak to możliwe kod.

+0

Pomaga wiedzieć, jak się za tym kryje. Co wiesz wcześniej i co wiesz tylko za iterację? Jakie są inne ograniczenia tego problemu? –

Odpowiedz

4

co przychodzi mi do głowy:

a = np.arange(1000) 
l = np.hstack(([1, 44, 66, 33, 90], np.arange(200, 300), np.arange(500, 600))) 
a[l] = 22 

Nie jestem pewien, czy jest to najprostszy sposób, ale działa.

Edytuj: masz rację, że jest wolniejsze niż używanie plasterków; ale nie można utworzyć obiektu slice z dowolnymi wartościami. Może powinieneś po prostu zrobić kilka zadań, a następnie:

%timeit a[np.hstack(([1, 44, 66, 33, 90], np.arange(200, 300), np.arange(500, 600)))] = 22 
10000 loops, best of 3: 39.5 us per loop 

%timeit a[[1, 44, 66, 33, 90]] = 22; a[200:300] = 22; a[500:600] = 22 
100000 loops, best of 3: 18.4 us per loop 
+0

Ale ta metoda nie używa plasterków, które są bardzo szybkie w odniesieniu do indeksowania tablicy. Działa, ale nie jest wydajny. – Giggi

+0

@Giggi True; edytowane. Nie wiem, czy istnieje sposób, aby osiągnąć to, co chcesz. –

0

Możesz użyć wymyślnego indeksowania, aby zbudować listę indeksów.

l = numpy.array([1,44,66,33,90]+range(200,300)+range(500,600)) 
a[l] = 22 

Ale jak @Lev zauważył, to nie może być szybciej (choć to prawie na pewno będzie, jeśli można wcześniej obliczyć listę indeksu).

Jednak wymyślne indeksowanie dotyczy jednej osi. Możesz więc wymyślić indeks na jednej osi i pokroić inne, jeśli to w ogóle pomoże:

a = numpy.random.randn(4, 5, 6) 
l = numpy.array([1, 2]) 
a[l, slice(None), slice(2, 4)] = 10