2015-07-02 13 views
5

Mam rzadką macierz, która jest przekształcana ze sklearn tfidfVectorier. Wierzę, że niektóre wiersze są zerowymi rzędami. Chcę je usunąć. Jednak z tego co wiem, istniejące wbudowane funkcje, np. nonzero() i eliminuj_zero() koncentrują się na wpisach zerowych, a nie na wierszach.scipy sparse matrix: usuń wiersze, których wszystkie elementy są zerowe

Czy istnieje łatwy sposób na usunięcie wszystkich zerowych rzędów z rzadkiej macierzy?

Przykład: Co mam teraz (a właściwie w formacie rozrzedzony):

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

Co chcę uzyskać:

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

Odpowiedz

2

Nie są istniejące funkcje do tego, ale to nie jest zbyt źle, aby napisać własną:

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

Najpierw przekonwertuj macierz naFormat. Jest to ważne, ponieważ macierze CSR przechowują swoje dane w postaci potrójnej wartości (data, indices, indptr), gdzie data przechowuje niezerowe wartości, indices przechowuje indeksy kolumn, a indptr przechowuje informacje o indeksie wiersza. Docs lepiej wyjaśnić:

indeksy kolumn dla rzędu i są przechowywane w indices[indptr[i]:indptr[i+1]] i odpowiadające im wartości są przechowywane w data[indptr[i]:indptr[i+1]].

Aby więc znaleźć wiersze bez żadnych niezerowych wartości, możemy po prostu spojrzeć na kolejne wartości M.indptr. Kontynuując naszą funkcję z góry:

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

Drugą zaletą formatu CSR jest to, że jest to stosunkowo tani pokroić wierszy, które upraszcza tworzenie macierzy wynikowej.

1

Dzięki za odpowiedź, @perimosocordiae

po prostu znaleźć inne rozwiązanie sam. Zamieszczam tutaj na wypadek, gdyby ktoś potrzebował go w przyszłości.

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

Odcinanie + getnnz() załatwia sprawę:

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

współpracuje bezpośrednio na csr_array. Można również usunąć wszystkie 0 kolumny bez zmiany formatów:

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

Jednak jeśli chcesz usunąć zarówno trzeba

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

nie jestem pewien dlaczego, ale

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

nie praca.