Remove/set the non-zero diagonal elements of a sparse matrix in scipy

diagonal, python, scipy, sparse-matrix

Solution

Based on @hpaulj's comment, I created an IPython Notebook which can be seen on nbviewer. This shows that out of all methods mentioned the following is the fastest (assume that `mat` is a sparse CSR matrix):

mat - scipy.sparse.dia_matrix((mat.diagonal()[scipy.newaxis, :], [0]), shape=(one_dim, one_dim))

Problem

Say I would like to remove the diagonal from a `scipy.sparse.csr_matrix`. Is there an efficient way of doing so? I saw that in the `sparsetools` module there are `C` functions to return the diagonal. Based on other SO answers here and here my current approach is the following: ``` def csr_setdiag_val(csr, value=0): """Set all diagonal nonzero elements (elements currently in the sparsity pattern) to the given value. Useful to set to 0 mostly. """ if csr.format != "csr": raise ValueError('Matrix given must be of CSR format.') csr.sort_indices() pointer = csr.indptr indices = csr.indices data = csr.data for i in range(min(csr.shape)): ind = indices[pointer[i]: pointer[i + 1]] j = ind.searchsorted(i) # matrix has only elements up until diagonal (in row i) if j == len(ind): continue j += pointer[i] # in case matrix has only elements after diagonal (in row i) if indices[j] == i: data[j] = value ``` which I then follow with ``` csr.eliminate_zeros() ``` Is that the best I can do without writing my own `Cython` code?

Original source

Related problems