Für ein dichtes Array ist es relativ einfach, diese Art der Multiplikation durchzuführen. Und schnell, da Aufschneiden schnell
In [453]: x=np.arange(24).reshape(4,6)
In [454]: y=np.arange(10,22).reshape(3,4)
In [457]: x[:3,:4] *= y
In [458]: x
Out[458]:
array([[ 0, 11, 24, 39, 4, 5],
[ 84, 105, 128, 153, 10, 11],
[216, 247, 280, 315, 16, 17],
[ 18, 19, 20, 21, 22, 23]])
Mit den spärlichen Mitteln
In [460]: xM=sparse.csr_matrix(x)
In [462]: yM=sparse.csr_matrix(y)
Geschnittene mehrfach funktioniert:
In [468]: z= xM[:3,:4].multiply(yM) # z.A matches the dense block
Aber wir bekommen eine Warnung, wenn versucht wird, diesen Wert zuweisen zurück auf xM
In [469]: xM[:3,:4] = xM[:3,:4].multiply(yM)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
In [471]: xL=sparse.lil_matrix(x)
In [472]: yL=sparse.lil_matrix(y)
In [475]: xL[:3,:4]=xL[:3,:4].multiply(yL)
xL.multiply
Code ist eigentlich: return self.tocsr().multiply(other)
Ich weiß nicht, welche Kombination von Formaten am effizientesten ist.
[Wir könnten die CSR-Sparsity-Warnung umgehen, indem wir erkennen, dass xM[:3,:4].multiply(yM)
weniger, nicht mehr Elemente ungleich Null haben wird. Also könnten wir zumindest vorübergehend einige Werte von xM.data
auf 0 setzen, ohne die anderen Attribute zu ändern. Wir können später mit eliminate_zeros
aufzuräumen.]
Eine Alternative zur geschnitten Zuordnung, y
auf die Größe des x
zu erweitern ist, und die vollständige Multiplikation durchzuführen. In diesem Fall müssen wir y
mit 1en auffüllen.
würde die dichte Version sein:
In [478]: z=np.ones_like(x)
In [479]: z[:3,:4]=y
In [480]: x*z
Mit dünn besetzten Matrizen wir bei der erforderlichen Polsterung suchen. Wenn yM
nur wenige Zeilen und/oder Spalten kleiner als xM
ist, vermute ich, dass wir sparse.vstack
und hstack
effizient verwenden können. Wenn es viel Padding gibt, wird das Ergebnis viele von Null verschiedene Werte haben, also können wir auch das dichte z
machen.
In [503]: zM = sparse.vstack((yM,np.ones((1,4),int)))
In [504]: zM = sparse.hstack((zM,np.ones((4,2),int)))
In [505]: zM.shape
Out[505]: (4, 6)
In [507]: zM.A
Out[507]:
array([[10, 11, 12, 13, 1, 1],
[14, 15, 16, 17, 1, 1],
[18, 19, 20, 21, 1, 1],
[ 1, 1, 1, 1, 1, 1]], dtype=int32)
In [511]: xM.multiply(zM).A
Out[511]:
array([[ 0, 11, 24, 39, 4, 5],
[ 84, 105, 128, 153, 10, 11],
[216, 247, 280, 315, 16, 17],
[ 18, 19, 20, 21, 22, 23]], dtype=int32)
Ein anderer Weg, dies mit yM
sparse.bmat
erweitert zu bauen, das eine neue Matrix aus Blöcken macht. bmat
funktioniert durch Konstruieren coo
formatieren Matrizen und verketten alle ihre row, col, data
Attribute, und daraus eine neue Matrix.
Wie sich herausstellt vstack
verwendet bmat
return bmat([[b] for b in blocks], format=format, dtype=dtype)
Diese Konstrukte die gleiche 4x6-Matrix:
In [520]: zM = sparse.bmat([[yM, np.ones((3,2),int)],
[np.ones((1,4),int), np.ones((1,2),int)]])
=================
Eine andere Möglichkeit ist die Anpassung von @ Vadims dok
Ansatz von sum
Problem
https://stackoverflow.com/a/37241977/901925
Es ist iterativ und stark abhängig von der Anzahl der Nicht-Null-Elemente der kleineren Matrix - aber es ist ziemlich flexibel.
Die Matrizen müssen nicht so groß sein, wie Sie das Problem definiert haben ... einfach eine '1' setzen, wo Sie keinen passenden Eintrag in der zweiten Matrix haben. Um sie elementweise zu multiplizieren, müssen die Dimensionen der Ersatzmatrizen gleich sein. – gariepy
Großartig, wie schlägst du vor, ich habe eine "1" überall, wo ich keinen passenden Eintrag habe? Denken Sie daran, dass meine Matrizen sehr groß sind - das Iterieren dauert lange. –
Ich bin versucht, dies ein Duplikat Ihrer anderen Frage über das Hinzufügen von Matrizen unterschiedlicher Form zu nennen. Die gleichen Probleme und mögliche Lösungen gelten: http://stackoverflow.com/questions/37231163/adding-two-csc-sparse-matrices-of-different-shapes-in-python – hpaulj