2016-06-29 12 views
1

Ich habe eine lange Reihe von 3-mal-3-Matrizen, zBNumPy: Dot Produkt für viele kleine Matrizen auf einmal

import numpy as np 

A = np.array([ 
    [[1, 2, 3], 
    [3, 4, 5], 
    [4, 5, 1]], 
    [[2, 0, 3], 
    [5, 1, 5], 
    [4, 2, 1]] 
    ]) 

und für jeden der kleinen Matrizen, ich möchte ausführen ein äußeres Produkt dot(a, a.T). Die Liste Verständnis

import numpy as np 

B = np.array([ 
    np.dot(a, a.T) for a in A 
    ]) 

funktioniert, aber nicht gut. Eine mögliche Verbesserung könnte sein, nur ein große dot Produkt zu tun, aber ich habe Probleme hier Einrichten A richtig dafür.

Irgendwelche Hinweise?

Antwort

2

Sie können die Liste der transponierten Matrizen als A.swapaxes(1, 2) erhalten, und die Liste der Produkte wollen Sie als A @ A.swapaxes(1, 2).

import numpy as np 

A = np.array([ 
    [[1, 2, 3], 
    [3, 4, 5], 
    [4, 5, 1]], 
    [[2, 0, 3], 
    [5, 1, 5], 
    [4, 2, 1]] 
    ]) 

B = np.array([ 
    np.dot(a, a.T) for a in A 
    ]) 

C = A @ A.swapaxes(1, 2) 

(B==C).all()  # => True 

Die @ operator ist nur syntaktischer Zucker für np.matmul, um die sich der documentation sagt, dass "wenn entweder Argument ND ist, N> 2, es als ein Stapel von Matrizen behandelt wird, in den letzten beiden Indizes und Broadcast-Wohnsitz entsprechend. "

1

Wenn man sich den Code genauer ansieht und versucht, ein größeres Bild zu bekommen, werden einige Informationen angezeigt. Die erste Achse benötigt eine Ausrichtung zwischen A und ihrer transponierten Version, da wir für beide Versionen im Code durch die erste Achse iterieren. Dann gibt es eine Reduktion entlang der dritten Achse sowohl in A als auch in seiner transponierten Version. Um die Ausrichtung beizubehalten und eine solche Punktproduktreduzierung durchzuführen, gibt es eine gute vektorisierte Option in np.einsum. Somit unserem Fall zu lösen, würde die Umsetzung wie folgt aussehen -

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