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 …

  • Variable Bereichsschwelle zur Identifizierung von Objekten - Python
  • Unterschied zwischen Python float und numpy float32
  • NumPy k-th diagonale Indizes
  • Plotten des Eigenvektors der Kovarianzmatrix mit matplotlib und np.linalg
  • Wie kann man ein Dichte-Plot in Matplotlib erstellen?
  • 3d zufällige Stichproben [duplizieren]
  • Wie entfernen Sie eine Spalte aus einem strukturierten numpy Array?
  • Numpy: Der Wahrheitswert eines Arrays mit mehr als einem Element ist zweideutig
  • 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.