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

Mun*_*ong 6 python numpy scipy scikit-learn

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

有没有简单的方法从稀疏矩阵中删除全零行?

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

[ [0, 0, 0]
  [1, 0, 2]
  [0, 0, 1] ]
Run Code Online (Sandbox Code Playgroud)

我想得到什么:

[ [1, 0, 2]
  [0, 0, 1] ]
Run Code Online (Sandbox Code Playgroud)

Dan*_*ler 9

切片+ getnnz()可以解决问题:

M = M[M.getnnz(1)>0]
Run Code Online (Sandbox Code Playgroud)

直接工作csr_array.您也可以删除所有0列而不更改格式:

M = M[:,M.getnnz(0)>0]
Run Code Online (Sandbox Code Playgroud)

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

M = M[M.getnnz(1)>0][:,M.getnnz(0)>0] #GOOD
Run Code Online (Sandbox Code Playgroud)

我不知道为什么但是

M = M[M.getnnz(1)>0, M.getnnz(0)>0] #BAD
Run Code Online (Sandbox Code Playgroud)

不起作用.


per*_*iae 5

没有现有的功能,但编写自己的功能也不错:

def remove_zero_rows(M):
  M = scipy.sparse.csr_matrix(M)
Run Code Online (Sandbox Code Playgroud)

首先,将矩阵转换为CSR(压缩稀疏行)格式。这很重要,因为 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]
Run Code Online (Sandbox Code Playgroud)

此处 CSR 格式的第二个好处是对行进行切片相对便宜,这简化了结果矩阵的创建。