Numpy elementares Produkt von 3D-Array

Ich habe zwei 3d Arrays A und B mit Form (N, 2, 2), die ich gern nach der N-Achse mit einem Matrixprodukt auf jeder der 2×2 Matrix multiplizieren möchte. Mit einer Loop-Implementierung sieht es so aus

C[i] = dot(A[i], B[i]) 

Gibt es einen Weg, den ich tun könnte, ohne eine Schleife zu benutzen? Ich habe in Tensordot geschaut, aber es war nicht in der Lage, es zu arbeiten. Ich glaube, ich möchte etwas wie tensordot(a, b, axes=([1,2], [2,1])) aber das gibt mir eine NxN Matrix.

  • Gibt es eine Möglichkeit, mehrere Standardwerte auf einem Python-Dict mit einem anderen Dict zu setzen?
  • Drucken Sie alle Unique Values ​​in einem Python Dictionary
  • 2 Werte in einem Datensatz-Array mit Django-Vorlage für Loop anzeigen
  • Wie überprüfe ich, ob ein Schlüssel in einem inneren Wörterbuch in einem Wörterbuch in Python existiert?
  • Lesen einer Datei Zeile für Zeile in Elemente eines Arrays in Python
  • Python-Konvertierung * Args zur Liste
  • 2 Solutions collect form web for “Numpy elementares Produkt von 3D-Array”

    Es scheint, dass du Matrix-Multiplikationen für jede Scheibe entlang der ersten Achse machst. Für das gleiche können Sie np.einsum wie so verwenden –

     np.einsum('ijk,ikl->ijl',A,B) 

    Runtime-Tests und Ergebnisse überprüfen –

     In [179]: N = 10000 ...: A = np.random.rand(N,2,2) ...: B = np.random.rand(N,2,2) ...: ...: def einsum_based(A,B): ...: return np.einsum('ijk,ikl->ijl',A,B) ...: ...: def forloop(A,B): ...: N = A.shape[0] ...: C = np.zeros((N,2,2)) ...: for i in range(N): ...: C[i] = np.dot(A[i], B[i]) ...: return C ...: In [180]: np.allclose(einsum_based(A,B),forloop(A,B)) Out[180]: True In [181]: %timeit forloop(A,B) 10 loops, best of 3: 54.9 ms per loop In [182]: %timeit einsum_based(A,B) 100 loops, best of 3: 5.92 ms per loop 

    Sie müssen nur die Operation auf der ersten Dimension Ihrer Tensoren durchführen, die mit 0 :

     c = tensordot(a, b, axes=(0,0)) 

    Dies wird funktionieren, wie Sie es wünschen. Auch brauchst du keine Liste von Achsen, denn es ist nur eine Dimension, die du den Betrieb ausführt. Mit den axes([1,2],[2,1]) vervielfachst du die 2. und 3. Dimension. Wenn Sie es in der Indexnotation schreiben (Einstein Summing Convention), entspricht dies c[i,j] = a[i,k,l]*b[j,k,l] , also vergeben Sie die Indizes, die Sie wollen behalten.

    EDIT: Ok, das Problem ist, dass das Tensor-Produkt eines zwei 3D-Objekts ein 6d-Objekt ist. Da Kontraktionen Paare von Indizes beinhalten, gibt es keine Möglichkeit, dass du ein 3D-Objekt durch einen tensordot Betrieb tensordot . Der Trick ist, Ihre Berechnung in zwei Teile zu teilen: Zuerst machst du den tensordot auf dem Index, um die Matrixoperation zu machen, und dann nimmst du eine Tensor-Diagonale, um dein 4d-Objekt auf 3d zu reduzieren. In einem Befehl:

     d = np.diagonal(np.tensordot(a,b,axes=()), axis1=0, axis2=2) 

    In der Tensor-Notation d[i,j,k] = c[i,j,i,k] = a[i,j,l]*b[i,l,k] .

    Python ist die beste Programmiersprache der Welt.