Wie gebe ich die Funktion auf das Drittel-Dimension-Array effektiv mit numpy?

Ich möchte eine beliebige Funktion auf 3d-ndarray als Element anwenden, die (3-dimensionales) Array für seine Argumente verwendet und scalar zurückgibt. Als Ergebnis sollten wir 2d-Matrix erhalten.

ZB) Pseudocode

A = [[[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]]] A.apply_3d_array(sum) ## or apply_3d_array(A,sum) is Okey. >> [[6,15],[24,33]] 

Ich verstehe es ist möglich mit Loop mit ndarray.shape Funktion, aber direkten Indexzugriff ist ineffizient wie offizielles Dokument sagt. Gibt es effektiver als die Schleife?

 def chromaticity(pixel): geo_mean = math.pow(sum(pixel),1/3) return map(lambda x: math.log(x/geo_mean),pixel ) 

2 Solutions collect form web for “Wie gebe ich die Funktion auf das Drittel-Dimension-Array effektiv mit numpy?”

Angesichts der Funktionsimplementierung konnten wir sie mit NumPy ufuncs vektorisieren, die auf dem gesamten Eingabefeld A in einem NumPy ufuncs arbeiten würden und somit die math Bibliotheksfunktionen vermeiden, die keine Vektorisierung auf Arrays unterstützen. In diesem Prozess würden wir auch das sehr effiziente Vektorisierungswerkzeug mitbringen: NumPy broadcasting . Also, wir hätten eine solche Implementierung –

 np.log(A/np.power(np.sum(A,2,keepdims=True),1/3)) 

Beispiellauf und Verifikation

Die Funktionsimplementierung ohne das lamdba Konstrukt und die Einführung von NumPy-Funktionen anstelle von math Bibliotheksfunktionen würde so etwas aussehen –

 def chromaticity(pixel): geo_mean = np.power(np.sum(pixel),1/3) return np.log(pixel/geo_mean) 

Beispiellauf mit der iterativen Implementierung –

 In [67]: chromaticity(A[0,0,:]) Out[67]: array([-0.59725316, 0.09589402, 0.50135913]) In [68]: chromaticity(A[0,1,:]) Out[68]: array([ 0.48361096, 0.70675451, 0.88907607]) In [69]: chromaticity(A[1,0,:]) Out[69]: array([ 0.88655887, 1.02009026, 1.1378733 ]) In [70]: chromaticity(A[1,1,:]) Out[70]: array([ 1.13708257, 1.23239275, 1.31940413]) 

Beispiellauf mit der vorgeschlagenen vektorisierten Implementierung –

 In [72]: np.log(A/np.power(np.sum(A,2,keepdims=True),1/3)) Out[72]: array([[[-0.59725316, 0.09589402, 0.50135913], [ 0.48361096, 0.70675451, 0.88907607]], [[ 0.88655887, 1.02009026, 1.1378733 ], [ 1.13708257, 1.23239275, 1.31940413]]]) 

Runtime-Test

 In [131]: A = np.random.randint(0,255,(512,512,3)) # 512x512 colored image In [132]: def org_app(A): ...: out = np.zeros(A.shape) ...: for i in range(A.shape[0]): ...: for j in range(A.shape[1]): ...: out[i,j] = chromaticity(A[i,j]) ...: return out ...: In [133]: %timeit org_app(A) 1 loop, best of 3: 5.99 s per loop In [134]: %timeit np.apply_along_axis(chromaticity, 2, A) #@hpaulj's soln 1 loop, best of 3: 9.68 s per loop In [135]: %timeit np.log(A/np.power(np.sum(A,2,keepdims=True),1/3)) 10 loops, best of 3: 90.8 ms per loop 

Das ist der Grund, warum immer versuchen, in NumPy funcs bei der Vektorisierung von Sachen mit Arrays und arbeiten auf so viele Elemente in one-go wie möglich!

apply_along_axis ist entworfen, um diese Aufgabe einfach zu machen:

 In [683]: A=np.arange(1,13).reshape(2,2,3) In [684]: A Out[684]: array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]]) In [685]: np.apply_along_axis(np.sum, 2, A) Out[685]: array([[ 6, 15], [24, 33]]) 

Es ist in Wirklichkeit

 for all i,j: out[i,j] = func( A[i,j,:]) 

Kümmert sich um die Details. Es ist nicht schneller als diese Iteration selbst zu machen, aber es macht es einfacher.

Ein weiterer Trick ist, deinen Eingang auf 2d umzuwandeln, die einfachere 1d-Iteration durchzuführen und das Ergebnis neu zu machen

  A1 = A.reshape(-1, A.shape[-1]) for i in range(A1.shape[0]): out[i] = func(A1[i,:]) out.reshape(A.shape[:2]) 

Um die Dinge schneller zu machen, musst du in den Eingeweide der Funktion graben und herausfinden, wie man nicky Operationen auf mehr als einer Dimension kompiliert. Im einfachen Fall der sum kann diese Funktion bereits auf ausgewählten Achsen arbeiten.

  • NumPy: vektorisieren Summe von Abständen zu einem Satz von Punkten
  • Wie kann ich diesen Python-Code vektorisieren?
  • Beschleunigung der sequentiellen Überprüfung, wenn ein Punkt in einer Form in Python ist
  • Wie man die Softmax-Wahrscheinlichkeit einer mehrdimensionalen Matrix vektorisiert
  • Finden Sie numpy Vektoren in einem Satz schnell
  • Machen Sie ein numpy Array monoton ohne Python Loop
  • Verwirrung über Numpy's gelten auf der Achse und Listenverständnisse
  • Multiplizieren Sie zwei Matrix mit Spalten mit Python
  • Online-Version von scikit-Learn's TfidfVectorizer
  • Numpy.vectorize gibt falsche Werte zurück
  • Wie finde ich alle Elemente in einem numpy 2-dimensionalen Array, das mit einer bestimmten Liste übereinstimmt?
  • Python ist die beste Programmiersprache der Welt.