2014-07-07 11 views
6

Ostrzegam z góry: Mogę być całkowicie zdezorientowany w tej chwili. Opowiadam krótką historię o tym, co faktycznie próbuję osiągnąć, ponieważ może to wyjaśnić. Powiedzmy, że mam f(a,b,c,d,e) i chcę znaleźć arg max (d,e) f(a,b,c,d,e). Rozważmy (trywialny przykład) Discretized siatki F od f:Oceń macierz na specyficznej subarray

F = np.tile(np.arange(0,10,0.1)[newaxis,newaxis,:,newaxis,newaxis], [10, 10, 1, 10, 10]) 
maxE = F.max(axis=-1) 
argmaxD = maxE.argmax(axis=-1) 
maxD = F.max(axis=-2) 
argmaxE = maxD.argmax(axis=-1) 

Jest to przypadek jak ja zazwyczaj rozwiązać wersję Discretized. Ale teraz załóżmy, że chcę rozwiązać arg max d f(a,b,c,d,e=X): Zamiast optymalnie wybranego e dla każdego innego wejścia, e jest stałe i podane (o rozmiarze AxBxCxD, który w tym przykładzie byłby 10x10x100x10). Mam problemy z rozwiązaniem tego.

Moje naiwne podejście było

X = np.tile(np.arange(0,10)[newaxis,newaxis,:,newaxis], [10,10,1,10]) 
maxX = F[X] 
argmaxD = maxX.argmax(axis=-1) 

Jednak ogromny przypływ pamięci awarii mojego IDE oznacza, że ​​F[X] nie jest widocznie co szukałem.

Wydajność jest kluczowa.

+0

wydaje się to, co chcesz, jest coś takiego: 'np.argmax (np.max (F, oś = -1), oś = -1)' –

Odpowiedz

2

Wierzę, że można zrobić to w ten sposób, ale być może istnieje lepszy sposób ..

n = 10 
F = np.tile(np.arange(0,n,0.1)[None,None,:,None,None], [n, n, 1, n, n]) 
X = np.tile(np.arange(0,n)[None,None,:,None], [n, n, 1, n]) 

a,b,c,d = np.ogrid[:n,:n,:n,:n] 
argmaxD = F[a,b,c,d,X].argmax(axis=-1) 

Przede X nie zajmuje całej przestrzeni, jak mówiliśmy w komentarzach. Jeśli chcesz wybrać e dla wszystkich a, b, c i d można zrobić np .:

X = np.tile(np.arange(0,n,0.1).astype(int)[None,None,:,None], [n, n, 1, n]) 
a,b,c,d = np.ogrid[:n,:n,:100,:n] 
argmaxD = F[a,b,c,d,X].argmax(axis=-1) 

Zauważ też, że zamiast tile mogła skorzystać z nadawania. Ale wtedy F[a,b,c,d,X] ma osobliwy wymiar więc należy podać coś podobnego axis=3:

X = np.arange(0,n,0.1).astype(int)[None,None,:,None] 
a,b,c,d = np.ogrid[:n,:n,:100,:n] 
argmaxD = F[a,b,c,d,X].argmax(axis=3) 
+0

bez pełnego trawienia, co się dzieje tutaj: Mój stary 'argmaxD '(ze standardowej maksymalizacji) miało kształt' (10L, 10L, 100L) ', natomiast' argmaxD', które podałeś ma kształt '(10L, 10L, 10L)'. Ponieważ jest to optymalny maksymalizator podany '(a, b, c)', który ma kształt '(10, 10, 100)', to nie może być poprawne. – FooBar

+0

@FooBar, już zauważyłem inny rozmiar w jednym z wymiarów, ale jest to wynikiem wyboru 'X = np.tile (np.arange (0, n), ...' Myślę, że powinieneś po prostu wprowadzić krokiem "0.1" .Powinieneś także użyć 'np.ogrid [: n,: n,: 100,: n]' –

+0

stepsize "0.1" daje "IndexError", ponieważ musi być liczbą całkowitą. zawierać wartości całkowite dla tego, co wybraliśmy z siatki dla 'e'.' e' zawiera elementy '100'. Oznacza to, że musimy wybrać pomiędzy' (0, 99) 'dla' e', prawda? Próbowałem 'X = np.tile (np.arange (0,100) ...)', ale dostaję "IndexError" ... Wiem, że popełniam błąd, nie mogę tego po prostu zauważyć. – FooBar

0

byłby to mój pomysł, aby rozwiązać ten problem.

from itertools import product, starmap 

f = lambda a,b,c,d,e : d/e 

args_iterable = product([1],[2],[3],range(1,1000),range(1,1000)) 

max_val, max_args = max(starmap(lambda *args: (f(*args), args) , args_iterable)) 

print max_args 
Powiązane problemy