Element-wise power of scipy.sparse matrix
Asked Answered
H

2

18

How do I raise a scipy.sparse matrix to a power, element-wise? numpy.power should, according to its manual, do this, but it fails on sparse matrices:

>>> X
<1353x32100 sparse matrix of type '<type 'numpy.float64'>'
        with 144875 stored elements in Compressed Sparse Row format>

>>> np.power(X, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../scipy/sparse/base.py", line 347, in __pow__
    raise TypeError('matrix is not square')
TypeError: matrix is not square

Same problem with X**2. Converting to a dense array works, but wastes precious seconds.

I've had the same problem with np.multiply, which I solved using the sparse matrix's multiply method, but there seems to be no pow method.

Heraclid answered 21/6, 2011 at 20:27 Comment(3)
I'm not familiar enough with numpy to tell you the answer, but your code doesn't contradict the documentation. The second argument to numpy.power should not be a number, but another matrix.Ichnography
It looks like it's calling the object's __pow__ method, which is attempting to square the entire matrix, rather than doing it elementwise. That fails because, as it says, the matrix isn't square.Starla
@RoundTower: actually, the second element should be an array, which it not the same as a matrix in Numpy, but a scalar is the same as a (1,) or (1,1) array for the purposes of numpy.power on a dense array.Heraclid
B
12

This is a little low-level, but for element-wise operations you can work with the underlying data array directly:

>>> import scipy.sparse
>>> X = scipy.sparse.rand(1000,1000, density=0.003)
>>> X = scipy.sparse.csr_matrix(X)
>>> Y = X.copy()
>>> Y.data **= 3
>>> 
>>> abs((X.toarray()**3-Y.toarray())).max()
0.0
Brokenhearted answered 21/6, 2011 at 21:23 Comment(0)
F
22

I just ran into the same question and find that sparse matrix now supports element-wise power. For the case above, it should be:

 X.power(2)
Floatstone answered 9/4, 2017 at 7:19 Comment(3)
Is this for python 2.7?Splanchnology
this doesn't seem to be true for python 3.6Bromism
it might depend on the format of a sparse matrix, for csr it seems to workMacadam
B
12

This is a little low-level, but for element-wise operations you can work with the underlying data array directly:

>>> import scipy.sparse
>>> X = scipy.sparse.rand(1000,1000, density=0.003)
>>> X = scipy.sparse.csr_matrix(X)
>>> Y = X.copy()
>>> Y.data **= 3
>>> 
>>> abs((X.toarray()**3-Y.toarray())).max()
0.0
Brokenhearted answered 21/6, 2011 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.