Füge mehrere Matrix hinzu, ohne eine neue zu bauen

Sagen Sie, ich habe zwei Matrizen B und M und ich möchte die folgende Anweisung ausführen:

 B += 3*M 

Ich laufe diese Anweisung wiederholt aus, also will ich nicht jedes Mal die Matrix 3*M ( 3 kann ändern, es ist nur zu machen, dass ich nur ein Skalar-Matrix-Produkt machen) zu bauen. Ist es eine Numpy-Funktion, die diese Berechnung "an Ort und Stelle" macht?

Genauer gesagt habe ich eine Liste von Skalaren as und eine Liste von Matrizen Ms , ich möchte das "Punkt-Produkt" (das ist nicht wirklich eins seit den beiden Operanden sind von unterschiedlicher Art) der beiden, das heißt :

 sum(a*M for a, M in zip(as, Ms)) 

Die Funktion np.dot tut nicht was ich außer …

  • OpenGL erhält Projektionsmatrix
  • Richtiger Weg, um numpy.matrix zu C Doppelzeiger zu werfen
  • Die erste Reihe von numpy.ones wird immer noch nach der Referenzierung einer anderen Matrix belegt
  • Füllen Sie die Matrix mit transponierter Version
  • Vektoroperationen mit numpy
  • Wie funktioniert diese ein-heiße Vektor-Konvertierung?
  • 2 Solutions collect form web for “Füge mehrere Matrix hinzu, ohne eine neue zu bauen”

    Sie können np.tensordot

     np.tensordot(As,Ms,axes=(0,0)) 

    Oder np.einsum

     np.einsum('i,ijk->jk',As,Ms) 

    Beispiellauf –

     In [41]: As = [2,5,6] In [42]: Ms = [np.random.rand(2,3),np.random.rand(2,3),np.random.rand(2,3)] In [43]: sum(a*M for a, M in zip(As, Ms)) Out[43]: array([[ 6.79630284, 5.04212877, 10.76217631], [ 4.91927651, 1.98115548, 6.13705742]]) In [44]: np.tensordot(As,Ms,axes=(0,0)) Out[44]: array([[ 6.79630284, 5.04212877, 10.76217631], [ 4.91927651, 1.98115548, 6.13705742]]) In [45]: np.einsum('i,ijk->jk',As,Ms) Out[45]: array([[ 6.79630284, 5.04212877, 10.76217631], [ 4.91927651, 1.98115548, 6.13705742]]) 

    Ein anderer Weg, den Sie dies tun können, besonders wenn Sie die Lesbarkeit bevorzugen, ist, den Rundfunk zu nutzen .

    So könntest du ein 3D-Array aus den 1D- und 2D-Arrays erstellen und dann über die entsprechende Achse summieren:

     >>> Ms = np.random.randn(4, 2, 3) # 4 arrays of size 2x3 >>> As = np.random.randn(4) >>> np.sum(As[:, np.newaxis, np.newaxis] * Ms) array([[-1.40199248, -0.40337845, -0.69986566], [ 3.52724279, 0.19547118, 2.1485559 ]]) >>> sum(a*M for a, M in zip(As, Ms)) array([[-1.40199248, -0.40337845, -0.69986566], [ 3.52724279, 0.19547118, 2.1485559 ]]) 

    Allerdings ist es erwähnenswert, dass np.einsum und np.tensordot sind in der Regel viel effizienter:

     >>> %timeit np.sum(As[:, np.newaxis, np.newaxis] * Ms, axis=0) The slowest run took 7.38 times longer than the fastest. This could mean that an intermediate result is being cached. 100000 loops, best of 3: 8.58 µs per loop >>> %timeit np.einsum('i,ijk->jk', As, Ms) The slowest run took 19.16 times longer than the fastest. This could mean that an intermediate result is being cached. 100000 loops, best of 3: 2.44 µs per loop 

    Und das gilt auch für größere Zahlen:

     >>> Ms = np.random.randn(100, 200, 300) >>> As = np.random.randn(100) >>> %timeit np.einsum('i,ijk->jk', As, Ms) 100 loops, best of 3: 5.03 ms per loop >>> %timeit np.sum(As[:, np.newaxis, np.newaxis] * Ms, axis=0) 100 loops, best of 3: 14.8 ms per loop >>> %timeit np.tensordot(As,Ms,axes=(0,0)) 100 loops, best of 3: 2.79 ms per loop 

    Also np.tensordot funktioniert am besten in diesem Fall.

    Der einzige gute Grund, np.sum und Broadcasting zu benutzen, ist, den Code ein wenig lesbarer zu machen (hilft bei kleinen Matrizen).

    Python ist die beste Programmiersprache der Welt.