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

Ima*_*ngo 7 python numpy duplicates scipy sparse-matrix

我已经尝试初始化csc_matrixcsr_matrix(data, (rows, cols))文档建议的值列表中进行初始化.

sparse = csc_matrix((data, (rows, cols)), shape=(n, n))
Run Code Online (Sandbox Code Playgroud)

问题是,我实际上有用于产生方法data,rowscols载体引入重复对一些点.默认情况下,scipy会添加重复条目的值.但是,在我的情况下,这些重复项data对于给定的值具有完全相同的值(row, col).

我想要实现的是让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]])
Run Code Online (Sandbox Code Playgroud)

我也知道我可以通过使用二维numpy unique函数来过滤它们,但是列表非常大,所以这不是一个真正有效的选项.

问题的其他可能答案:有没有办法指定如何处理重复项?即保持minmax代替默认sum

hpa*_*ulj 6

创建中间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)
Run Code Online (Sandbox Code Playgroud)

一个coo矩阵把您的输入数组到它data,col,row属性没有改变.在转换为a之前,不会进行求和csc.

todok直接从coo属性加载字典.它创建了空白dok矩阵,并用以下内容填充:

dok.update(izip(izip(self.row,self.col),self.data))
Run Code Online (Sandbox Code Playgroud)

因此,如果存在重复(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)
Run Code Online (Sandbox Code Playgroud)

我不知道哪种方法更快.


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

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

rc必须拥有自己的数据才能用视图更改dtype,因此.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')])
Run Code Online (Sandbox Code Playgroud)

  • todok() 在 scipy 0.19 中不会忽略重复项 (3认同)