Scipy csr_matrix无法正确复制

时间:2015-07-23 00:37:00

标签: python scipy sparse-matrix

我从一个csr_matrix计算一些问题,并从结果中创建一个新的。在试图追踪它时,我只是做了一些简单的代码来复制原始矩阵,副本也不一样。我已经在非常小的矩阵上尝试过(如文档中所示),但在真实世界矩阵(大约2.5M条目,所有这些都是非零)上,结果是奇怪的。这是测试代码:

print type(X_ngrams)
tst = csr_matrix( (X_ngrams.data,X_ngrams.nonzero()))
print "Original:"
print "shape     ", X_ngrams.shape
r1,c1=X_ngrams.nonzero()
print "rows, cols", r1[:10],c1[:10]
print "indptr    ", X_ngrams.indptr[:10]
print "indices   ", X_ngrams.indices[:10]
print "data[:10] ", X_ngrams.data[:10]
#
print
print "Copy:"
print "shape     ", tst.shape
r2,c2=tst.nonzero()
print "rows, cols", r2[:10],c2[:10]
print "indptr    ", tst.indptr[:10]
print "indices   ", tst.indices[:10]
print "data[:10] ", tst.data[:10]

结果如下:

<class 'scipy.sparse.csr.csr_matrix'>
Original:
shape      (2257, 202262)
rows, cols [0 0 0 0 0 0 0 0 0 0] [ 69627  70494 168418 174006 157892     161787 146945 148354  51951  53422]
indptr     [   0  518 1247 3156 3634 4368 5594 6670 8540 9257]
indices    [ 69627  70494 168418 174006 157892 161787 146945 148354  51951  53422]
data[:10]  [ 2  1 23  1 35  1 11  1  8  1]

Copy:
shape      (2257, 202262)
rows, cols [0 0 0 0 0 0 0 0 0 0] [1439 2461 2561 2683 2748 4279 6212 6275 6332 6611]
indptr     [   0  518 1247 3156 3634 4368 5594 6670 8540 9257]
indices    [1439 2461 2561 2683 2748 4279 6212 6275 6332 6611]
data[:10]  [20  1  1  1  1  1  1  1  1  1]

为什么副本的结构不同?我需要创建的矩阵应该具有完全相同的结构,每个位置只有一个不同的数字。

1 个答案:

答案 0 :(得分:1)

我无法使用您提供的数据复制您的问题,但我怀疑问题在于X_ngrams未被排序,而副本已排序。排序由nonzero执行。

比较2 indices。两者都是第一行中500+值的小样本:

indices    [ 69627  70494 168418 174006 157892 161787 146945 148354  51951  53422]
indices    [1439 2461 2561 2683 2748 4279 6212 6275 6332 6611]

第二个列表较小,并已排序。 X_ngrams.has_sorted_indices的价值是什么?

你真正需要比较的是两者的nonzero

一种解决方案是先排序X_ngrams

 X._ngrams.sort_indices()  # sort in place

您也可以考虑使用M.copy()M.tocsr(copy=True)M.sorted_indices()返回带有排序标记的副本。

此格式:

sparse.csr_matrix((M.data, M.indices, M.indptr))

使用相同的数组M制作副本。或者如果你想让它们成为副本:

sparse.csr_matrix((M.data.copy(), M.indices.copy(), M.indptr.copy()))