How can I perform element-wise operations (e.g. modulo) for a scipy.sparse.coo_matrix?
Do I have to create a NumPy dense array from it? If that's the case won't I lose all the benefits gained from creating a sparse matrix?
As long as the element-wise operation does not change the sparsity of the data, you can use the .data
attribute, e.g.:
import scipy as sp
import scipy.sparse
m = (sp.sparse.rand(5, 10, 0.2) * 100).astype(int)
print(m)
(1, 0) 34
(1, 2) 2
(2, 2) 39
(1, 4) 54
(3, 4) 22
(4, 4) 46
(1, 6) 40
(1, 7) 97
(4, 8) 60
(4, 9) 97
m.data %= 10
print(m)
(1, 0) 4
(1, 2) 2
(2, 2) 9
(1, 4) 4
(3, 4) 2
(4, 4) 6
(1, 6) 0
(1, 7) 7
(4, 8) 0
(4, 9) 7
This should be efficient and should not have any conversion overhead.
Note that this can be done for any operation for which zero 0
is the absorbing element, at least on one side (left or right) for non-symmetric (commutative) operations.
For example, in the modulo %
operation, 0
is the left-absorbing element, since 0 % a = 0
for any a
. The same is true for integer division //
, division /
(as long as 0.0
and -0.0
distinction is not needed) and exponentiation **
(for positive numbers). For multiplication *
, 0
is the absorbing element.
For the case of element-wise multiplication *
and /
(by a scalar at least) are supported with the regular syntax by scipy.sparse.coo_matrix
objects.