2015-03-06 15 views
7

Jeśli mam funkcję, f (x), która przyjmuje pojedynczą tablicę 1d jako argument i tworzy tablicę 1d jako wyjście, mogę użyć funkcji numpy.apply_along_axis, aby zastosować tę funkcję do każdego wiersza 2d-tablica X, której wiersze są poprawnymi argumentami dla f.Python apply_along_axis wielu tablic

Teraz chcę zrobić analogiczną rzecz z funkcją, która bierze dwa argumenty. E.g. Mam funkcję f (x, y), która przyjmuje argumenty tablicy 1d jako argumenty, a także mam dwie tablice 2d X, Y obie z n wierszami. Chcę zastosować f do każdej pary wierszy, tworząc tablicę, która ma ponownie n wierszy.

Jak to osiągnąć w skuteczny sposób?

ja również zainteresowany wariantów, gdzie F zajmuje więcej argumentów lub wyższe tablic trójwymiarowych uczestniczą:

Na przykład może przyjąć f 3 tablice X, Y, Z w postaci (2,2); (3,); (5,) i dają wynik kształtu (4,4).

Mam X, Y, Z kształtów (50, 100, 2, 2); (50, 100, 3); (50, 100, 5) i chcesz uzyskać wynik kształtu (50, 100, 4, 4)

Odpowiedz

6

Patrząc na kod dla numpy.apply_along_axis Widzę, że po prostu iteruje nad innymi wymiarami, stosując swoją funkcję do każdego z nich " rząd'. Jest dodatkowy kod, który umożliwia wymiarach około 2. Ale 2d X sprowadza się do:

result = np.empty_like(X) 
for i, x in enumerate(X): 
    result[i] = func1d(x) 

tam również kod wywnioskować, jaki kształt powinna mieć result. Na przykład jeśli func1d jest np.sum, to result będzie 1d, a nie 2d jak wejście.

W tej funkcji nie ma specjalnej "wydajności". Rozszerzenie wieloma wejściami może być normalny Python zip:

result = np.empty_like(X) 
for i,(x,y) in enumerate(zip(X,Y)): 
    result[i] = func1d(x,y) 

np.ndindex to poręczne narzędzie do tworzenia indeksów. Warto spojrzeć na jego kod. Wykorzystuje się numpy iteracyjnej ogólnego przeznaczenia np.nditer, który patrz: http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html

Dla przykładu F 3 może się tablice X, Y, Z w postaci (2,2); (3,); (5,) i dają wynik kształtu (4,4).

Mam X, Y, Z kształtów (50, 100, 2, 2); (50, 100, 3); (50, 100, 5) i chcą na skutek kształtu (50, 100, 4, 4)

for i,j in np.ndindex(50,100): 
    result[i,j,:,:] = f(X[i,j,:,:], Y[i,j,:,:], Z[i,j,:,:]) 

':' nie są konieczne, ale było jasne, że mamy do indeksowania w dniu 2 wymiarów i kroić resztę. Będą one wymagane, jeśli chcesz wykonać iterację w 1 i 3 wymiarach, i wyciąć drugą.

+0

wow, dziękuję! Myślałem, że zawsze uważam, że apply_along_axis byłaby bardziej wydajna niż pętla for. –

Powiązane problemy