忽略稀疏矩阵中的重复条目

2022-04-13 00:00:00 python numpy scipy sparse-matrix duplicates

问题描述

我尝试从(data, (rows, cols))值列表中初始化csc_matrixcsr_matrix,正如文档所建议的那样。

sparse = csc_matrix((data, (rows, cols)), shape=(n, n))
问题是,我实际用于生成datarowscols向量的方法为某些点引入了重复项。默认情况下,scipy将重复条目的值相加。然而,在我的例子中,对于给定的(row, col),这些重复项在data中具有完全相同的值。

我试图实现的是让Scipy忽略第二个条目(如果已经存在),而不是添加它们。

忽略我可以改进生成算法以避免生成重复项的事实,是否有参数或其他方法可以创建忽略重复项的稀疏矩阵?

当前有两个data = [4, 4]; cols = [1, 1]; rows = [1, 1];条目生成稀疏矩阵,(1,1)处的值为8,而所需值为4

>>> c = csc_matrix(([4, 4], ([1,1],[1,1])), shape=(3,3))
>>> c.todense()
matrix([[0, 0, 0],
        [0, 8, 0],
        [0, 0, 0]])

我还知道我可以使用二维NumPyunique函数来筛选它们,但列表非常大,因此这实际上不是一个有效的选项。

问题的其他可能答案:有什么方法可以指定如何处理重复项?即保留minmax而不是默认的sum


解决方案

创建中间矩阵dok在您的示例中起作用:

In [410]: c=sparse.coo_matrix((data, (cols, rows)),shape=(3,3)).todok().tocsc()

In [411]: c.A
Out[411]: 
array([[0, 0, 0],
       [0, 4, 0],
       [0, 0, 0]], dtype=int32)
coo矩阵将您的输入数组原封不动地放入其datacolrow属性中。除非将其转换为csc,否则不会进行求和。

todok直接从coo属性加载词典。它创建空的dok矩阵,并用:

填充
dok.update(izip(izip(self.row,self.col),self.data))

因此,如果有重复的(row,col)值,则是剩余的最后一个值。这使用标准的Python字典散列来查找唯一键。


这里有一种使用np.unique的方法。我必须构造一个特殊的对象数组,因为unique在1D上操作,而我们有一个2D索引。

In [479]: data, cols, rows = [np.array(j) for j in [[1,4,2,4,1],[0,1,1,1,2],[0,1,2,1,1]]]

In [480]: x=np.zeros(cols.shape,dtype=object)

In [481]: x[:]=list(zip(rows,cols))

In [482]: x
Out[482]: array([(0, 0), (1, 1), (2, 1), (1, 1), (1, 2)], dtype=object)

In [483]: i=np.unique(x,return_index=True)[1]

In [484]: i
Out[484]: array([0, 1, 4, 2], dtype=int32)

In [485]: c1=sparse.csc_matrix((data[i],(cols[i],rows[i])),shape=(3,3))

In [486]: c1.A
Out[486]: 
array([[1, 0, 0],
       [0, 4, 2],
       [0, 1, 0]], dtype=int32)

我不知道哪种方法更快。


另一种获取唯一索引的方法,如liuengo's链接:

rc = np.vstack([rows,cols]).T.copy()
dt = rc.dtype.descr * 2
i = np.unique(rc.view(dt), return_index=True)[1]

rc必须拥有自己的数据才能使用VIEW更改数据类型,因此.T.copy()

In [554]: rc.view(dt)
Out[554]: 
array([[(0, 0)],
       [(1, 1)],
       [(2, 1)],
       [(1, 1)],
       [(1, 2)]], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])

相关文章