2012-09-02 21 views
5

Si tiene una matriz dispersa X:elementos de multiplicarse en una matriz dispersa en la matriz con filas

>> 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]] 

y una matriz Y:

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

... ¿Cómo se puede multiplicar cada elemento de la X por las filas de Y. por ejemplo:

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

o:

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

he cansado pero obviamente esto no funciona ya que las dimensiones no coinciden: Z = X.data * Y

Respuesta

8

Desafortunadamente el método de la matriz de la RSE parece .multiply para densificar la matriz si el otro es densa. Por lo que esta sería una forma de evitar que:

# 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)) 

Esto crea algunos temporales, pero al menos es totalmente vectorizado, y no densificar la matriz dispersa.


Para una matriz de COO el equivalente es:

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

Para una matriz CSC el equivalente sería:

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

¿Sería también trabajar con matrices COO? – Zach

+1

No, para COO, tendría que hacer 'Z.data * = Y [Z.row]' Creo, o np.take en lugar de indexar si le importa la velocidad. – seberg

+0

Eso funciona. Lo hace sin densificar la matriz ¿verdad? – Zach

Cuestiones relacionadas