Wie geht MATLAB damit um?
numpy
hat eine besondere Funktion dieses wiederholte Index Fall zu behandeln, die add.at
Using ufunc.at on matrix
Dies hat für scipy.sparse
nicht umgesetzt worden.
Da sparse
Summen Koordinaten wiederholt, wenn von einem coo
Format csr
eine Umwandlung, vermute ich, dieses Problem in einer Weise gegossen werden könnte, der Vorteil, dass statt. In der Tat hat die csr
Matrix eine M.sum_duplicates
Methode.
Ich müsste herumspielen, um die Details zu erarbeiten.
In [876]: M = sparse.csr_matrix((3, 4), dtype=float)
In [877]: M
Out[877]:
<3x4 sparse matrix of type '<class 'numpy.float64'>'
with 0 stored elements in Compressed Sparse Row format>
demonstriert die np.add.at
Aktion:
In [878]: arr = M.A
In [879]: arr[[0,0,0,0,0],[0,1,0,1,0]] += 1
In [880]: arr
Out[880]:
array([[ 1., 1., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
In [883]: arr = M.A
In [884]: np.add.at(arr,[[0,0,0,0,0],[0,1,0,1,0]],1)
In [885]: arr
Out[885]:
array([[ 3., 2., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
zu M
Hinzufügen erzeugt die gleiche Wirkung gepuffert - mit einer Warnung. Die Veränderung der Seltenheit einer Matrix ist relativ teuer.
In [886]: M[[0,0,0,0,0],[0,1,0,1,0]] += 1
....
SparseEfficiencyWarning)
In [887]: M
Out[887]:
<3x4 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in Compressed Sparse Row format>
In [888]: M.A
Out[888]:
array([[ 1., 1., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
Der richtige Weg, um diese zusätzlich zu tun ist, eine neue Sparse Matrix mit den Werten zu machen, die hinzugefügt werden müssen. Wir können die Vorteile aus der Tatsache ziehen, dass coo
Stil Eingängen Summe mit umgewandelten Duplikaten zu csr
:
In [895]: m = sparse.csr_matrix((np.ones(5,int),([0,0,0,0,0],[0,1,0,1,0])), shape=M.shape)
In [896]: m
Out[896]:
<3x4 sparse matrix of type '<class 'numpy.int32'>'
with 2 stored elements in Compressed Sparse Row format>
In [897]: m.A
Out[897]:
array([[3, 2, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=int32)
jetzt können wir das Original und die neuen hinzufügen:
In [898]: M = sparse.csr_matrix((3, 4), dtype=float)
In [899]: M+m
Out[899]:
<3x4 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in Compressed Sparse Row format>
Bitte beachten Sie numpy die und scipy der docs zu lesen verstehe, was hier passiert. Die grundlegende Pipeline von Berechnungen (für einen vektorisierten Ansatz) könnte also wie folgt aussehen: A: Sortiere deine Orte (lex), B: erzeuge 1d-vec von Einsen, kombiniere Duples in A und summiere B parallel (Bs Dimension könnte abnehmen; einige Einträge können von 1 bis N wachsen, C: Fügen Sie diese B-Werte hinzu, indem Sie mit A indizieren. Ein viel einfacherer (schleifenbasierter Ansatz): greifen Sie einfach jeden Ort in einer Schleife und inkrementieren Sie (nacheinander). – sascha
Okay, danke. So habe ich es gemacht, aber ich habe erwartet, dass es eine schnellere Methode geben würde. Ich komme von MATLAB, also erwarte ich immer, dass Matrix-Operationen schneller sind als Schleifen. – HolyMonk
Ja in den meisten Fällen. Dann probiere einfach meinen ersten Ansatz (oder warte auf einige Experten, um etwas besseres zu präsentieren). – sascha