Wie unterscheidet sich Multiplikation für NumPy Matrix vs Array Klassen?

Die numpy docs empfehlen, Array anstelle von Matrix für die Arbeit mit Matrizen zu verwenden. Im Gegensatz zu Oktave (die ich bis vor kurzem benutzt habe), * führt keine Matrixmultiplikation durch, du musst die Funktion matrixmultipy () verwenden. Ich fühle das macht den Code sehr unleserlich.

Hat jemand meine Ansichten geteilt und hat eine Lösung gefunden?

  • Numpy ndarray Multiplikation Umstellung auf Matrix Multiplikation
  • Wie viel Zeit braucht der Zug SVM Klassifikator?
  • Warum ist nicht numpy.mean multithreaded?
  • Wie man numpy vom Rundfunk beim Erstellen eines Objekts Array von verschiedenen geformten Arrays zu halten
  • Ist es möglich, Referenz-Link zwischen Liste und numpy Array zu halten
  • Wie lese ich das Bild vom numpy Array in PIL Image?
  • Wie deklariere ich ein 2-dimensionales Array mit verschiedenen Zeilenlängen mit np.array?
  • Bestelltes farbiges plot nach dem clustering mit python
  • 7 Solutions collect form web for “Wie unterscheidet sich Multiplikation für NumPy Matrix vs Array Klassen?”

    Der Hauptgrund für die Verwendung der matrix Klasse ist, dass a) es ist inhärent zweidimensional, und b) gibt es zusätzliche Overhead im Vergleich zu einem "normalen" numpy Array. Wenn alles, was Sie tun, ist lineare Algebra, dann mit allen Mitteln, fühlen Sie sich frei, die Matrix-Klasse zu verwenden … Persönlich finde ich es mehr Mühe, als es sich lohnt.

    Für Arrays (vor Python 3.5), verwenden Sie dot statt matrixmultiply .

    Z.B

     import numpy as np x = np.arange(9).reshape((3,3)) y = np.arange(3) print np.dot(x,y) 

    Oder in neueren Versionen von numpy, verwenden Sie einfach x.dot(y)

    Persönlich finde ich es viel besser lesbarer als der * Operator, der Matrixmultiplikation bedeutet …

    Für Arrays in Python 3.5 verwenden Sie x @ y .

    Die wichtigsten Dinge zu wissen, für Operationen auf NumPy Arrays versus Operationen auf NumPy Matrizen sind:

    • NumPy-Matrix ist eine Unterklasse des NumPy-Arrays

    • NumPy- Array- Operationen sind elementweise (sobald die Sendung berücksichtigt wird)

    • NumPy- Matrixoperationen folgen den gewöhnlichen Regeln der linearen Algebra

    Einige Code-Snippets zu illustrieren:

     >>> from numpy import linalg as LA >>> import numpy as NP >>> a1 = NP.matrix("4 3 5; 6 7 8; 1 3 13; 7 21 9") >>> a1 matrix([[ 4, 3, 5], [ 6, 7, 8], [ 1, 3, 13], [ 7, 21, 9]]) >>> a2 = NP.matrix("7 8 15; 5 3 11; 7 4 9; 6 15 4") >>> a2 matrix([[ 7, 8, 15], [ 5, 3, 11], [ 7, 4, 9], [ 6, 15, 4]]) >>> a1.shape (4, 3) >>> a2.shape (4, 3) >>> a2t = a2.T >>> a2t.shape (3, 4) >>> a1 * a2t # same as NP.dot(a1, a2t) matrix([[127, 84, 85, 89], [218, 139, 142, 173], [226, 157, 136, 103], [352, 197, 214, 393]]) 

    Aber diese Operationen scheitern, wenn diese beiden NumPy-Matrizen in Arrays umgewandelt werden:

     >>> a1 = NP.array(a1) >>> a2t = NP.array(a2t) >>> a1 * a2t Traceback (most recent call last): File "<pyshell#277>", line 1, in <module> a1 * a2t ValueError: operands could not be broadcast together with shapes (4,3) (3,4) 

    Obwohl die NP.dot- Syntax mit Arrays arbeitet ; Diese Operationen funktionieren wie Matrixmultiplikation:

     >> NP.dot(a1, a2t) array([[127, 84, 85, 89], [218, 139, 142, 173], [226, 157, 136, 103], [352, 197, 214, 393]]) 

    Also brauchst du jemals eine NumPy-Matrix? Dh ein NumPy-Array genügt für die lineare Algebra-Berechnung (vorausgesetzt, Sie kennen die richtige Syntax, dh NP.dot)?

    Die Regel scheint das zu sein, wenn die Argumente (Arrays) Formen haben (mxn), die mit der gegebenen linearen Algebra-Operation kompatibel sind, dann sind Sie in Ordnung, sonst wirft NumPy.

    Die einzige Ausnahme, die ich getroffen habe (es gibt wahrscheinlich andere) ist die Berechnung der Matrix invers .

    Unten sind Snippets, in denen ich eine reine lineare Algebra-Operation (in der Tat von Numpys Linear Algebra-Modul) genannt und in einem NumPy-Array übergeben wurde

    Determinante eines Arrays:

     >>> m = NP.random.randint(0, 10, 16).reshape(4, 4) >>> m array([[6, 2, 5, 2], [8, 5, 1, 6], [5, 9, 7, 5], [0, 5, 6, 7]]) >>> type(m) <type 'numpy.ndarray'> >>> md = LA.det(m) >>> md 1772.9999999999995 

    Eigenvektoren / Eigenwertpaare :

     >>> LA.eig(m) (array([ 19.703+0.j , 0.097+4.198j, 0.097-4.198j, 5.103+0.j ]), array([[-0.374+0.j , -0.091+0.278j, -0.091-0.278j, -0.574+0.j ], [-0.446+0.j , 0.671+0.j , 0.671+0.j , -0.084+0.j ], [-0.654+0.j , -0.239-0.476j, -0.239+0.476j, -0.181+0.j ], [-0.484+0.j , -0.387+0.178j, -0.387-0.178j, 0.794+0.j ]])) 

    Matrix Norm :

     >>>> LA.norm(m) 22.0227 

    Qr faktorisierung :

     >>> LA.qr(a1) (array([[ 0.5, 0.5, 0.5], [ 0.5, 0.5, -0.5], [ 0.5, -0.5, 0.5], [ 0.5, -0.5, -0.5]]), array([[ 6., 6., 6.], [ 0., 0., 0.], [ 0., 0., 0.]])) 

    Matrixrang:

     >>> m = NP.random.rand(40).reshape(8, 5) >>> m array([[ 0.545, 0.459, 0.601, 0.34 , 0.778], [ 0.799, 0.047, 0.699, 0.907, 0.381], [ 0.004, 0.136, 0.819, 0.647, 0.892], [ 0.062, 0.389, 0.183, 0.289, 0.809], [ 0.539, 0.213, 0.805, 0.61 , 0.677], [ 0.269, 0.071, 0.377, 0.25 , 0.692], [ 0.274, 0.206, 0.655, 0.062, 0.229], [ 0.397, 0.115, 0.083, 0.19 , 0.701]]) >>> LA.matrix_rank(m) 5 

    Matrixbedingung:

     >>> a1 = NP.random.randint(1, 10, 12).reshape(4, 3) >>> LA.cond(a1) 5.7093446189400954 

    Inversion erfordert eine NumPy- Matrix :

     >>> a1 = NP.matrix(a1) >>> type(a1) <class 'numpy.matrixlib.defmatrix.matrix'> >>> a1.I matrix([[ 0.028, 0.028, 0.028, 0.028], [ 0.028, 0.028, 0.028, 0.028], [ 0.028, 0.028, 0.028, 0.028]]) >>> a1 = NP.array(a1) >>> a1.I Traceback (most recent call last): File "<pyshell#230>", line 1, in <module> a1.I AttributeError: 'numpy.ndarray' object has no attribute 'I' 

    Aber das Moore-Penrose-Pseudoinverse scheint gut zu funktionieren

     >>> LA.pinv(m) matrix([[ 0.314, 0.407, -1.008, -0.553, 0.131, 0.373, 0.217, 0.785], [ 1.393, 0.084, -0.605, 1.777, -0.054, -1.658, 0.069, -1.203], [-0.042, -0.355, 0.494, -0.729, 0.292, 0.252, 1.079, -0.432], [-0.18 , 1.068, 0.396, 0.895, -0.003, -0.896, -1.115, -0.666], [-0.224, -0.479, 0.303, -0.079, -0.066, 0.872, -0.175, 0.901]]) >>> m = NP.array(m) >>> LA.pinv(m) array([[ 0.314, 0.407, -1.008, -0.553, 0.131, 0.373, 0.217, 0.785], [ 1.393, 0.084, -0.605, 1.777, -0.054, -1.658, 0.069, -1.203], [-0.042, -0.355, 0.494, -0.729, 0.292, 0.252, 1.079, -0.432], [-0.18 , 1.068, 0.396, 0.895, -0.003, -0.896, -1.115, -0.666], [-0.224, -0.479, 0.303, -0.079, -0.066, 0.872, -0.175, 0.901]]) 

    Es gibt eine Situation, in der der Punktoperator beim Umgang mit Arrays unterschiedliche Antworten geben wird, als mit dem Umgang mit Matrizen. Nehmen wir zum Beispiel an:

     >>> a=numpy.array([1, 2, 3]) >>> b=numpy.array([1, 2, 3]) 

    Lässt sie in Matrizen umwandeln:

     >>> am=numpy.mat(a) >>> bm=numpy.mat(b) 

    Nun können wir für die beiden Fälle eine andere Ausgabe sehen:

     >>> print numpy.dot(aT, b) 14 >>> print am.T*bm [[1. 2. 3.] [2. 4. 6.] [3. 6. 9.]] 

    In 3.5 bekam Python endlich einen Matrixmultiplikationsoperator . Die Syntax ist a @ b .

    Referenz von http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html

    …, wird die Verwendung der numpy.matrix- Klasse entmutigt , da sie nichts hinzufügt, was nicht mit 2D- Numpy.ndarray- Objekten erreicht werden kann und zu einer Verwirrung führen kann, welche Klasse verwendet wird. Beispielsweise,

     >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> A array([[1, 2], [3, 4]]) >>> linalg.inv(A) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> b = np.array([[5,6]]) #2D array >>> b array([[5, 6]]) >>> bT array([[5], [6]]) >>> A*b #not matrix multiplication! array([[ 5, 12], [15, 24]]) >>> A.dot(bT) #matrix multiplication array([[17], [39]]) >>> b = np.array([5,6]) #1D array >>> b array([5, 6]) >>> bT #not matrix transpose! array([5, 6]) >>> A.dot(b) #does not matter for multiplication array([17, 39]) 

    Scipy.linalg Operationen können gleichermaßen auf numpy.matrix oder auf 2D numpy.ndarray Objekte angewendet werden.

    Dieser Trick könnte das sein, was du suchst. Es ist eine Art einfache Bedienerüberlastung.

    Sie können dann so etwas wie die vorgeschlagene Infix-Klasse wie folgt verwenden:

     a = np.random.rand(3,4) b = np.random.rand(4,3) x = Infix(lambda x,y: np.dot(x,y)) c = a |x| b 

    Ein zutreffendes Zitat von PEP 465 – Ein dedizierter Infix-Operator für die Matrixmultiplikation , wie von @ petr-viktorin erwähnt, klärt das Problem, das das OP bekommen hat:

    […] numpy bietet zwei verschiedene Typen mit verschiedenen __mul__ Methoden. Für numpy.ndarray Objekte führt * eine elementare Multiplikation durch, und die Matrixmultiplikation muss einen Funktionsaufruf ( numpy.dot ) verwenden. Für numpy.matrix Objekte führt * eine Matrixmultiplikation durch, und die elementare Multiplikation erfordert die Funktionssyntax. Schreiben Code mit numpy.ndarray funktioniert gut. numpy.matrix mit numpy.matrix funktioniert auch gut. Aber die Mühe beginnt , sobald wir versuchen, diese beiden Stücke von Code zusammen zu integrieren. Code, der einen ndarray erwartet und eine matrix erhält, oder umgekehrt, kann abstürzen oder falsche Ergebnisse zurückgeben

    Die Einführung des @ infix-Betreibers sollte dazu beitragen, den Python-Matrix-Code zu vereinheitlichen und zu vereinfachen.

    Python ist die beste Programmiersprache der Welt.