在Scipy中创建稀疏矩阵时覆盖而不是添加重复的三元组
问题描述
在Scipy中,要从三重格式数据(行、列和数据数组)创建稀疏矩阵,默认行为是对所有重复项的数据值求和。我可以将此行为更改为覆盖(或不执行任何操作)吗?例如:
import scipy.sparse as sparse
rows = [0, 0]
cols = [0, 0]
data = [1, 1]
S = sparse.coo_matrix((data, (rows, cols)))
此处,S.todense()
等于matrix([[2]])
,但我希望它是matrix([[1]])
。
在documentation of sparse.coo_matrix中,显示为
默认情况下,转换为CSR或CSC格式时,会复制(i,j) 参赛作品将汇总在一起。这有助于提高效率 有限元矩阵的构造等。
从该公式看,可能存在默认选项以外的其他选项。
解决方案
我在Scipy GitHub上看到了关于对此汇总进行更多控制的讨论,但我不知道有任何生产上的变化。正如文件显示的那样,对重复项求和是一个由来已久的传统。
创建时,coo
矩阵不求和;它只是将参数分配给它的属性:
In [697]: S = sparse.coo_matrix((data, (rows, cols)))
In [698]: S.data
Out[698]: array([1, 1])
In [699]: S.row
Out[699]: array([0, 0], dtype=int32)
In [700]: S.col
Out[700]: array([0, 0], dtype=int32)
转换为密集(或CSR/CSC)确实合计,但不会改变S
本身:
In [701]: S.A
Out[701]: array([[2]])
In [702]: S.data
Out[702]: array([1, 1])
您可以使用以下命令原地执行求和:
In [703]: S.sum_duplicates()
In [704]: S.data
Out[704]: array([2], dtype=int32)
我不知道有什么方法既可以删除重复项,也可以绕过该操作。我可以查一下相关的问题。
=
S.todok()
进行原地求和(即,更改S
)。查看该代码,我看到它称为self.sum_duplicates
。以下代码复制了不带总和的数据:
In [727]: dok=sparse.dok_matrix((S.shape),dtype=S.dtype)
In [728]: dok.update(zip(zip(S.row,S.col),S.data))
In [729]: dok
Out[729]:
<1x1 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in Dictionary Of Keys format>
In [730]: print(dok)
(0, 0) 1
In [731]: S
Out[731]:
<1x1 sparse matrix of type '<class 'numpy.int32'>'
with 2 stored elements in COOrdinate format>
In [732]: dok.A
Out[732]: array([[1]])
这是一个字典更新,因此最终的值是最后一个重复项。我在其他地方发现dok.update
是将值添加到稀疏矩阵的一种相当快的方法。
tocsr
固有地进行求和;tolil
使用tocsr
;因此这种todok
方法可能是最简单的。
相关文章