2015-07-02 163 views
5

我有一个从sklearn tfidfVectorier转换的稀疏矩阵。我相信有些行是全零行。我想删除它们。然而,就我所知,现有的内置功能,例如nonzero()和eliminate_zero(),注重零条目,而不是行。scipy稀疏矩阵:删除所有元素为零的行

是否有任何简单的方法来从稀疏矩阵中删除全零行?

例子: 我现在有什么(实际上是稀疏格式):

[ [0, 0, 0] 
    [1, 0, 2] 
    [0, 0, 1] ] 

我要得到什么:

[ [1, 0, 2] 
    [0, 0, 1] ] 

回答

2

有不存在的功能,但它不是太不好写自己的:

def remove_zero_rows(M): 
    M = scipy.sparse.csr_matrix(M) 

首先,将矩阵转换为CSR (compressed sparse row)格式。这很重要,因为CSR矩阵将其数据存储为(data, indices, indptr)的三元组,其中data保存非零值,indices存储列索引,并且indptr保存行索引信息。该文档更好地解释:

对行的列指数i存储在 indices[indptr[i]:indptr[i+1]]及其相应的值存储在data[indptr[i]:indptr[i+1]]

因此,要查找没有任何非零值的行,我们可以看看连续值M.indptr。从上面继续我们的功能:

num_nonzeros = np.diff(M.indptr) 
    return M[num_nonzeros != 0] 

这里CSR格式的第二个好处是,它的价格相对便宜切片行,从而简化了产生的基质的创作。

1

感谢您的回复,@perimosocordiae

我只是觉得我自己另一种解决方案。我在这里发帖,以防将来有人需要它。

def remove_zero_rows(X) 
    # X is a scipy sparse matrix. We want to remove all zero rows from it 
    nonzero_row_indice, _ = X.nonzero() 
    unique_nonzero_indice = numpy.unique(nonzero_row_indice) 
    return X[unique_nonzero_indice] 
5

切片+ getnnz()的伎俩:直接

M = M[M.getnnz(1)>0] 

作品上csr_array。 您还可以删除所有0列,而不改变格式:

M = M[:,M.getnnz(0)>0] 

但是,如果你想删除这两个你需要

M = M[M.getnnz(1)>0][:,M.getnnz(0)>0] #GOOD 

我不知道为什么,但

M = M[M.getnnz(1)>0, M.getnnz(0)>0] #BAD 

不工作。