2016-12-26 16 views
9

Mam dwie trójwymiarowe tablice, aib, i chcę znaleźć podtablę 2D b z elementami, w których a miał minimum wzdłuż trzeciej osi, tj.Znajdź tablicę odpowiadającą minimalnym wartościom wzdłuż osi w innej macierzy.

a=n.random.rand(20).reshape((5,2,2)) 
b=n.arange(20).reshape((5,2,2)) 
c=n.argmin(a,2) #indices with minimal value of a 
d=n.zeros_like(c) #the array I want 
for i in range(5): 
    for j in range(2): 
    d[i,j] = b[i,j,c[i,j]] 

Czy istnieje sposób, aby uzyskać te wartości bez podwójnej pętli?

Jestem świadomy tej odpowiedzi: replace min value to another in numpy array ale jeśli chcę to do pracy dla moich tablic 3D musiałbym zrobić wiele operacji zmiany kształtu - i zastanawiam się, czy coś jest prostsze.

Odpowiedz

1

Oto Numpythonic sposób:

In [83]: x, y, z = a.shape 
In [84]: b[np.repeat(np.arange(x), y), np.tile(np.arange(y), x), c.ravel()].reshape(x, y) 

Tutaj np.repeat(np.arange(x), y) daje odpowiednie indeksy pierwszej osi.

In [86]: np.repeat(np.arange(x), y) 
Out[86]: array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]) 

poda odpowiednie wskaźniki drugiej osi.

In [87]: np.tile(np.arange(y), x) 
Out[87]: array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1]) 

I za trzecim można po prostu użyć spłaszczony kształt c.

In [88]: c.ravel() 
Out[88]: array([1, 0, 1, 1, 1, 0, 1, 1, 0, 0]) 
+0

Zmiana kształtu je do (5,2), a wynik powinien wyglądać 'mgrid' wersji z' ogrid' sugerowane przez inną odpowiedź. – hpaulj

+0

@hpaulj Tak, niestety nie znałem tej funkcji. – Kasramvd

3

Można użyć np.ogrid tworzyć siatkę o innych wymiarach:

x, y, z = arr.shape # assuming your array is named "arr" 
xyz = np.ogrid[0:x, 0:y] + [c] # c is your second axis index (the argmin) 
arr[xyz] 

Jeśli to nie jest ostatnia oś następnie można po prostu użyć insert ponieważ ogrid powraca normalny list pyton zawierającą indeksy.

+0

Wystarczy sprawdzić: n.ogrid [0: x, 0: y] + [c] dodaje trzeci wymiar do tablicy ostrid, z elementami c, prawda? Wygląda to bardzo podobnie do wymyślnej odpowiedzi (którą akceptuję, ponieważ jest jeszcze krótsza, ale jest to interesujące - dziękuję!). – mzzx

+0

@mzzx Zasadniczo podobne odpowiedzi, ponieważ obie tworzą rozgłaszane tablice zasięgu, aby indeksować do tablicy danych. Różnica polega właśnie na sposobie tworzenia tablic zasięgu. Mój post wyraźnie rozgłasza emisję, podczas gdy ten post robi to za pomocą funkcji. – Divakar

+0

@mzzx Tak, są one równoważne! Jeśli podoba ci się krótki, możesz również napisać go w jednym wierszu: arr [np.ogrid [0: arr.shape [0], 0: arr.shape [1]] + [c]] :-) – MSeifert

Powiązane problemy