2012-09-02 19 views
5

Jeśli masz rzadki macierzy X:Mnożenie elementów w rozrzedzony tablicy z wierszy w macierzy

>> X = csr_matrix([[0,2,0,2],[0,2,0,1]]) 
>> print type(X)  
>> print X.todense()  
<class 'scipy.sparse.csr.csr_matrix'> 
[[0 2 0 2] 
[0 2 0 1]] 

oraz macierz Y:

>> print type(Y) 
>> print text_scores 
<class 'numpy.matrixlib.defmatrix.matrix'> 
[[8] 
[5]] 

... Jak można pomnożyć każdy element X przez rzędy Y. na przykład

[[0*8 2*8 0*8 2*8] 
[0*5 2*5 0*5 1*5]] 

, czyli

[[0 16 0 16] 
[0 10 0 5]] 

Mam dość tego, ale oczywiście to nie działa jak wymiary nie meczów: Z = X.data * Y

Odpowiedz

8

Niestety metoda macierzy CSR .multiply wydaje zagęszczenia matrycę jeśli druga jest gęsta. Więc będzie to jeden ze sposobów uniknięcia tego, że:

# Assuming that Y is 1D, might need to do Y = Y.A.ravel() or such... 

# just to make the point that this works only with CSR: 
if not isinstance(X, scipy.sparse.csr_matrix): 
    raise ValueError('Matrix must be CSR.') 

Z = X.copy() 
# simply repeat each value in Y by the number of nnz elements in each row: 
Z.data *= Y.repeat(np.diff(Z.indptr)) 

To stwarza pewne temporaries, ale przynajmniej jego pełni wektorowy, a nie zagęszczenia rzadki matrycy.


Dla COO matrix równoważnika:

Z.data *= Y[Z.row] # you can use np.take which is faster then indexing. 

Na matrycy CSC odpowiednik może być:

Z.data *= Y[Z.indices] 
+0

Byłoby również pracować z matryc COO? – Zach

+1

Nie, dla COO musisz wykonać 'Z.data * = Y [Z.row]' Myślę, że lub np.take zamiast indeksowania, jeśli zależy Ci na szybkości. – seberg

+0

To działa. Czyni to bez zagęszczania matrycy, prawda? – Zach