scipy稀疏矩阵:删除所有元素为零的行

Posted

技术标签:

【中文标题】scipy稀疏矩阵:删除所有元素为零的行【英文标题】:scipy sparse matrix: remove the rows whose all elements are zero 【发布时间】:2015-09-20 04:38:47 【问题描述】:

我有一个从 sklearn tfidfVectorier 转换而来的稀疏矩阵。我相信有些行是全零行。我想删除它们。但是,据我所知,现有的内置函数,例如nonzero() 和 Elimination_zero(),专注于零条目,而不是行。

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

示例: 我现在拥有的(实际上是稀疏格式):

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

我想得到什么:

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

【问题讨论】:

【参考方案1】:

切片 + 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

不工作。

【讨论】:

【参考方案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 格式的第二个好处是对行进行切片相对便宜,这简化了结果矩阵的创建。

【讨论】:

【参考方案3】:

感谢您的回复,@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]

【讨论】:

X 必须是 csr,但这有效。我无法让其他方法为我工作。

以上是关于scipy稀疏矩阵:删除所有元素为零的行的主要内容,如果未能解决你的问题,请参考以下文章

什么是数据结构中的特殊矩阵和稀疏矩阵

如何点积 (1,10^13) (10^13,1) scipy 稀疏矩阵

python中scipy学习——随机稀疏矩阵及操作

Scipy 稀疏矩阵作为 DataFrame 列

scipy稀疏矩阵

用布尔数组索引 SciPy 稀疏矩阵