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 …

  • Matrizen mit verschiedenen Etiketten und verschiedenen Abmessungen hinzufügen
  • Ersetzen Sie den Teilteil der Matrix durch eine andere kleine Matrix in numpy
  • Binarize eine spärliche Matrix in python auf eine andere Weise
  • Multiplizieren von sehr großem 2D-Array in Python
  • Sortieren Sie eine Numpy Python-Matrix nacheinander nach Zeilen
  • 2d Array von Listen in Python
  • 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.