# Python: multiplication of sparse matrices slower in csr_matrix than numpy

I am trying to multiply a sparse matrix with itself using numpy and scipy.sparse.csr_matrix. The size of matrix is 128x256. Its 93% values are 0. Ironically the multiplication using numpy is faster than scipy.sparse. I do not know why? The code I am using is:

import numpy,time
W=numpy.random.choice([0, 1], size=(128,256), p=[0.93,0.07])
start=time.time()
W1=numpy.matmul(W,numpy.transpose(W))
end=time.time()
print(end-start)

from scipy.sparse import csr_matrix
start=time.time()
W1=csr_matrix(W).dot(csr_matrix(W).transpose())
end=time.time()
print(end-start)


Numpy gives time 0.0006 and scipy gives 0.004. Why. Comparing times for dense matrix, numpy gives smaller time on dense matrix as well and scipy takes more time. Why is the time for scipy.sparse not less than numpy for sparse matrix

• did you try to increase the size of the matrix and see how the computation time evolves in both cases ? – Robin Nicole Jul 3 '19 at 15:28
• @RobinNicole replicating the same matrix to get size (384, 256). Numpy gives time: 0.003 and scipy gives 0.01. Time has increased in both. But again numpy gives lesser time than scipy – shaifali Gupta Jul 3 '19 at 15:31
• If I were you I would try it for matrices of size 2^6 x 2^6, 2^7 x 2^7, 2^7 x 2^7, 2^7 x 2^7... until 2^18 x 2^18 for example and you might see that for small size matrices numpy works better than scipy but that when you start to have larg-ish matrices scipy gets better. Could you also provide a piece of code ? – Robin Nicole Jul 3 '19 at 16:06
• @RobinNicole The piece of code is given in the question. I will try changing sizes of matrices – shaifali Gupta Jul 3 '19 at 16:19
• It s not reproducible code, you do not have any library import or places where you define your matrices – Robin Nicole Jul 3 '19 at 16:28

Here, you do not time only the time taken to make the matrix multiplication but also the time taken to convert your matrix from dense to sparse. If you convert your matrix before the timing starts, you will see that multiplication with scipy is indeed more than twice faster

import time, numpy, scipy
from scipy.sparse import csr_matrix
import numpy as np

W = np.random.binomial(n=1, p=0.01, size=(100, 100))
start=time.time()
numpy.matmul(W,numpy.transpose(W))
end=time.time()
dt_dense = end - start
print ('time taken for the dense matrix {}'.format(end - start))

sparse_W = csr_matrix(W)
start=time.time()
sparse_W.dot(sparse_W.transpose())
end=time.time()
dt_sparse = end - start
print ('time taken for the sparse matrix {}'.format(end - start))
dt_dense/dt_sparse

• Since, I want to compare the overhead of sparse and dense matrices. I would prefer to include csr_matrix conversion within the time itself. – shaifali Gupta Jul 3 '19 at 16:49
• If you put the sparse_W after the timing the scipy will still be slightly faster because you will do the conversion only once instead of twice in the implementation of your question, would it be alright for you. Otherwise could you share what problem you want to solve with this piece of code and maybe I can give you a hand – Robin Nicole Jul 3 '19 at 16:54
• Yes, as you said it is slightly fast. But I realized my original matrix has floating point entries with 8 digits of precision. Can this be the reason for csr_matrix to give more time for my actual matrix? – shaifali Gupta Jul 3 '19 at 17:18
• Yes I guess float is the problem. Because in your code as well if I change some entries to float. The time for scipy increases – shaifali Gupta Jul 3 '19 at 17:41
• I do not know I can only advise you to try and see – Robin Nicole Jul 4 '19 at 10:07