2015-07-02 102 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 

不工作。