我们说我有两个稀疏矩阵,确切地说scipy.sparse.csr_matrix
,我想添加元素,添加的问题是它们对每个行和列都有一个ID,对应一句话。
例如,一个矩阵可能具有与['cat', 'hat']
对应的列和行,按特定顺序排列。然后,另一个矩阵可以具有与['cat', 'mat', 'hat']
对应的列和行。这意味着在添加这些矩阵时,我需要考虑以下事项:
我无法找到解决此合并问题的方法,并希望您能帮助我找到答案。
为了更加清晰,以下是一个例子:
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]])
非常感谢任何帮助!
答案 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