If you have a sparse matrix X:
>> 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]]
And a matrix Y:
>> print type(Y)
>> print text_scores
<class 'numpy.matrixlib.defmatrix.matrix'>
[[8]
[5]]
...How can you multiply each element of X by the rows of Y. For example:
[[0*8 2*8 0*8 2*8]
[0*5 2*5 0*5 1*5]]
or:
[[0 16 0 16]
[0 10 0 5]]
I've tired this but obviously it doesn't work as the dimensions dont match:
Z = X.data * Y
To multiply one matrix with another, we need to check first, if the number of columns of the first matrix is equal to the number of rows of the second matrix. Now multiply each element of the column of the first matrix with each element of rows of the second matrix and add them all.
You can multiply any row by a number. (This means multiplying every entry in the row by the same number.) In this example, we have multiplied Row 3 of the matrix by 13 .
Unfortunatly the .multiply
method of the CSR matrix seems to densify the matrix if the other one is dense. So this would be one way avoiding that:
# 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))
This does create some temporaries, but at least its fully vectorized, and it does not densify the sparse matrix.
For a COO matrix the equivalent is:
Z.data *= Y[Z.row] # you can use np.take which is faster then indexing.
For a CSC matrix the equivalent would be:
Z.data *= Y[Z.indices]
Something I use to perform row-wise (resp. column-wise) multiplication is to use matrix multiplication with a diagonal matrix on the left (resp. on the right):
import numpy as np
import scipy.sparse as sp
X = sp.csr_matrix([[0,2,0,2],
[0,2,0,1]])
Y = np.array([8, 5])
D = sp.diags(Y) # produces a diagonal matrix which entries are the values of Y
Z = D.dot(X) # performs D @ X, multiplication on the left for row-wise action
Sparsity is preserved (in CSR format):
print(type(Z))
>>> <class 'scipy.sparse.csr.csr_matrix'>
And the output is also correct:
print(Z.toarray()) # Z is still sparse and gives the right output
>>> print(Z.toarray()) # Z is still sparse and gives the right output
[[ 0. 16. 0. 16.]
[ 0. 10. 0. 5.]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With