添加具有显式列和行顺序以及不同形状的稀疏矩阵

时间:2014-03-23 12:33:29

标签: python scipy sparse-matrix

我们说我有两个稀疏矩阵,确切地说scipy.sparse.csr_matrix,我想添加元素,添加的问题是它们对每个行和列都有一个ID,对应一句话。

例如,一个矩阵可能具有与['cat', 'hat']对应的列和行,按特定顺序排列。然后,另一个矩阵可以具有与['cat', 'mat', 'hat']对应的列和行。这意味着在添加这些矩阵时,我需要考虑以下事项:

  1. 矩阵可能有不同顺序的相应列和行。
  2. 矩阵的形状可能不同。
  3. 一个矩阵中的某些列和行可能不会出现在另一个矩阵中。
  4. 我无法找到解决此合并问题的方法,并希望您能帮助我找到答案。

    为了更加清晰,以下是一个例子:

    import scipy.sparse as sp
    mat1_id2column = ['cat', 'hat']
    mat1_id2row = ['cat', 'hat']
    mat2_id2column = ['cat', 'mat', 'hat']
    mat2_id2row = ['cat', 'mat', 'hat']
    
    mat1 = sp.csr_matrix([[1, 0], [0, 1]])
    mat2 = sp.csr_matrix([[1, 0, 1], [1, 0, 0], [0, 0, 1]])
    
    merge(mat1, mat2)
    
    #Expected output: 
    id2column = ['cat', 'hat', 'mat']
    id2row = ['cat', 'hat', 'mat']
    merged = sp.csr_matrix([[2, 1, 0], [0, 1, 0], [1, 0, 0]])
    

    非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

首先构建一个行id索引,它将是2个矩阵的行ID的并集。然后为列做同样的事情。使用此功能,您现在可以从旧矩阵中的坐标转换为新结果矩阵中的坐标。

你看到如何从那里完成它或者我应该更明确吗?

答案 1 :(得分:0)

以其他方式,您必须根据字符串和行/列索引计算出唯一的映射。

使用词典的开始是:

from collections import defaultdict

def foo(dd,mat):
    for ij,v in mat[0].todok().iteritems():
        dd[(mat[1][ij[0]],mat[2][ij[1]])] += v

dd=defaultdict(int)
foo(dd,(mat1,mat1_id2row,mat1_id2column))
foo(dd,(mat2,mat2_id2row,mat2_id2column))
print dd

产生

defaultdict(<type 'int'>, {('cat', 'hat'): 1, 
                           ('hat', 'hat'): 2, 
                           ('mat', 'cat'): 1, 
                           ('cat', 'cat'): 2})

dd可以转回dok


另一种方法会利用coo_matrix处理重复项的方式 - 将它们转换为csr时将它们加在一起。

在此示例中,将['cat', 'mat', 'hat']作为主索引。

mat2的2个定义数组是

data: array([1, 1, 1, 1])
row : array([0, 0, 1, 2])
col : array([0, 2, 0, 2])

对于mat1他们会(我还没有编写代码来执行此操作)

data: array([1, 1])
row : array([0, 2])
col : array([0, 2])

连接各个数组,并创建一个新的coo矩阵merged

data: array([1, 1, 1, 1, 1, 1])
row : array([0, 0, 1, 2, 0, 2])
col : array([0, 2, 0, 2, 0, 2])

merged.A将是

array([[2, 0, 1],
       [1, 0, 0],
       [0, 0, 2]])

另一种选择是使用矩阵乘法将数组映射到可以添加的较大数组。我再次留下如何生成未指定映射的细节。您必须为每个不同的单词序列生成单独的T。这可能需要与其他方法相同的迭代工作量。

T1 = sp.csr_matrix(np.array([[1,0],[0,0],[0,1]]))
T2 = T1.T # same mapping for row and cols of mat1
T1.dot(mat1).dot(T2) + mat2