3

I want to divide a sparse matrix's rows by scalars given in an array.

For example, I have a csr_matrix C :

C = [[2,4,6], [5,10,15]]
D = [2,5]

I want the result of C after division to be :

result = [[1, 2, 3], [1, 2, 3]]

I have tried this using the method that we use for numpy arrays:

result = C / D[:,None]

But this seems really slow. How to do this efficiently in sparse matrices?

maciejwww
  • 1,067
  • 1
  • 13
  • 26
user3787291
  • 217
  • 3
  • 12
  • An earlier question on row wise divide, https://stackoverflow.com/questions/44080315/division-of-sparse-matrix – hpaulj Mar 13 '18 at 16:03

4 Answers4

8

Approach #1

Here's a sparse matrix solution using manual replication with indexing -

from scipy.sparse import csr_matrix

r,c = C.nonzero()
rD_sp = csr_matrix(((1.0/D)[r], (r,c)), shape=(C.shape))
out = C.multiply(rD_sp)

The output is a sparse matrix as well as opposed to the output from C / D[:,None] that creates a full matrix. As such, the proposed approach saves on memory.

Possible performance boost with replication using np.repeat instead of indexing -

val = np.repeat(1.0/D, C.getnnz(axis=1))
rD_sp = csr_matrix((val, (r,c)), shape=(C.shape))

Approach #2

Another approach could involve data method of the sparse matrix that gives us a flattened view into the sparse matrix for in-place results and also avoid the use of nonzero, like so -

val = np.repeat(D, C.getnnz(axis=1))
C.data /= val
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • 1
    Awesome! It worked like a charm! On my dataset my method was taking 60 seconds. And now it is taking 1 second. Thanks. – user3787291 Mar 13 '18 at 11:19
  • @user3787291 How about `Approach #2`? – Divakar Mar 13 '18 at 11:27
  • 1
    yes it worked too. And what if i need to divide column wise ? How do you divide column wise ? – user3787291 Mar 17 '18 at 20:39
  • @user3787291 I got stuck in this problem but had to do it for column wise. There's just one small modification needed. **(1.0/D)[r]** changes to **(1.0/D)[c]** `rD_sp = csr_matrix(((1.0/D)[c], (r,c)), shape=(C.shape))` – Bhavul Jan 22 '19 at 11:57
0

Question: I want to divide a sparse matrix's rows by scalars given in an array. For example: C = [[2,4,6], [5,10,15]] D = [2,5]

Answer : use "multiply" provided by sparse matrix interface - it allows to "pointwise" multiply matrices by matrices as well as by vectors and scalars

    C = [[2,4,6], [5,10,15]]
    D = [2,5]

from scipy.sparse import csr_matrix

c = csr_matrix(C)
c2 = c.multiply( 1/np.array(D).reshape(2,1) )

c2.toarray()

'output:' array([[ 2, 4, 6], [ 5, 10, 15]], dtype=int64)

PS

Thanks to Alexander Kirillin

Alexander Chervov
  • 616
  • 3
  • 7
  • 23
-1

one line code: result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]

C = [[2,4,6], [5,10,15]] #len(C[0]) = 3
D = [2,5] # len(D) = 2
result = [[C[i][j]/D[i] for j in range(len(C[0]))] for i in range(len(D))]
print result
Yarn
  • 84
  • 4
-1

If you first cast D to type numpy.matrix (which I'm assuming you can do unless D is too big to fit into memory), then you can just run

C.multiply(1.0 / D.T)

to get what you want.

Joe Silverstein
  • 406
  • 5
  • 7