MATLAB如何處理這個問題?
numpy
都有特定的功能來處理這種重複指示的情況下,add.at
Using ufunc.at on matrix
這尚未爲scipy.sparse
實施。
由於sparse
在將coo
格式轉換爲csr
格式時重複了座標之和,我懷疑可以利用該格式轉換此問題。實際上,csr
矩陣有一個M.sum_duplicates
方法。我不得不四處弄清楚細節。
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>
展示np.add.at
行動:
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.]])
添加到M
產生相同的緩衝作用 - 一個警告。改變矩陣的稀疏性相對昂貴。
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.]])
正確的方式做,這除了是使一個新的稀疏矩陣與需要添加的值。我們可以採取的事實,即coo
風格的投入總和與轉換爲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)
現在我們可以添加原始和新:
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>
請考慮閱讀numpy的年代和SciPy的的文檔,以瞭解這裏發生了什麼。因此,計算的基本流水線(對於矢量化方法)可能是:A:對你的位置進行排序(lex),B:創建一個1d-vec的對象,在A中合併模糊,同時對B進行求和(B的尺寸可能會減小;條目可能會從1增加到N),C:在使用A進行索引時添加這些B值。一個更簡單的(基於循環的方法):只需抓取循環中的每個位置並逐個遞增。 – sascha
好的,謝謝。這就是我這樣做的方式,但預計會有一個更快的方法。 我來自MATLAB,所以我總是期望矩陣操作比循環更快。 – HolyMonk
在大多數情況下是。然後試試我的第一種方法(或者等待一些專家提出更好的方法)。 – sascha