it-swarm.com.de

numpy Matrixvektormultiplikation

Wenn ich zwei numpy Arrays mit den Größen (n x n) * (n x 1) multipliziere, erhalte ich eine Größenmatrix (n x n). Nach normalen Matrixmultiplikationsregeln wird ein (n x 1) -Vektor erwartet, aber ich kann einfach keine Informationen darüber finden, wie dies in Pythons Numpy-Modul erfolgt.

Die Sache ist, dass ich es nicht manuell implementieren möchte, um die Geschwindigkeit des Programms zu erhalten.

Beispielcode ist unten gezeigt:

a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])

print a*b
   >>
   [[5 2 9]
   [1 2 3]
   [1 4 3]]

Was ich will ist:

print a*b
   >>
   [16 6 8]
153
user3272574

Einfachste Lösung

Verwenden Sie _numpy.dot_ oder a.dot(b). Siehe die Dokumentation hier .

_>>> a = np.array([[ 5, 1 ,3], 
                  [ 1, 1 ,1], 
                  [ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])
_

Dies liegt daran, dass numpy-Arrays keine Matrizen sind und die Standardoperationen _*, +, -, /_ für Arrays elementweise funktionieren. Stattdessen können Sie versuchen, numpy.matrix zu verwenden, und _*_ wird wie eine Matrixmultiplikation behandelt.


Andere Lösungen

Wissen Sie auch, dass es andere Optionen gibt:

  • Wie unten erwähnt, funktioniert der Operator _@_ bei Verwendung von python3.5 + wie erwartet:

    _>>> print(a @ b)
    array([16, 6, 8])
    _
  • Wenn Sie einen Overkill wünschen, können Sie numpy.einsum verwenden. Die Dokumentation gibt Ihnen einen Vorgeschmack darauf, wie es funktioniert, aber ehrlich gesagt habe ich es erst richtig verstanden, als ich diese Antwort gelesen und einfach alleine damit herumgespielt habe.

    _>>> np.einsum('ji,i->j', a, b)
    array([16, 6, 8])
    _
  • Ab Mitte 2016 (Anzahl 1.10.1) können Sie das experimentelle numpy.matmul ausprobieren, das wie _numpy.dot_ funktioniert, mit zwei Hauptausnahmen: Keine Skalarmultiplikation, aber es funktioniert mit Stacks von Matrizen.

    _>>> np.matmul(a, b)
    array([16, 6, 8])
    _
  • numpy.inner funktioniert genauso wie _numpy.dot_ für die Matrix-Vektor-Multiplikation, verhält sich jedoch anders für die Matrix -Matrix- und Tensormultiplikation (siehe Wikipedia bezüglich der Unterschiede zwischen dem inneren Produkt und dem Punktprodukt im Allgemeinen oder siehe diese SO Antwort bezüglich der Implementierungen von numpy).

    _>>> np.inner(a, b)
    array([16, 6, 8])
    
    # Beware using for matrix-matrix multiplication though!
    >>> b = a.T
    >>> np.dot(a, b)
    array([[35,  9, 10],
           [ 9,  3,  4],
           [10,  4,  6]])
    >>> np.inner(a, b) 
    array([[29, 12, 19],
           [ 7,  4,  5],
           [ 8,  5,  6]])
    _

Seltenere Optionen für Edge-Fälle

  • Wenn Sie Tensoren haben (Arrays mit einer Dimension größer oder gleich eins), können Sie numpy.tensordot mit dem optionalen Argument _axes=1_ verwenden:

    _>>> np.tensordot(a, b, axes=1)
    array([16,  6,  8])
    _
  • Verwenden Sie nicht numpy.vdot, wenn Sie eine Matrix komplexer Zahlen haben, da die Matrix auf abgeflacht wird Wenn Sie ein 1D-Array erstellen, wird versucht, das komplexe konjugierte Punktprodukt zwischen der abgeflachten Matrix und dem Vektor zu finden (was aufgrund einer Größeninkongruenz _n*m_ vs. n fehlschlägt).

243
wflynny