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.

  • Warum Numpy hat Dimension (n,) anstelle von (n, 1) nur
  • Konvertieren Sie Array als String formatiert - Python
  • Erstellen Sie ein Dict von Listen aus einer Zeichenfolge
  • Python - Zugriff auf Werte, die in Wörterbüchern verschachtelt sind
  • Wie benutzt man einen Punkt ".", Um auf Mitglieder des Wörterbuchs zuzugreifen?
  • Zuordnen von numpy Daten in Zython zu einer Ansicht
  • 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.