2
votes

I have a 256x256 csr_matrix in scipy and I have a list of a new row order that I'd like to apply. I tried this:

def HblockDiag(z):
        Hz = H(z) # H(z) returns a 256x256 csr_matrix
        Hz.indices = idenRows
        return Hz

but it didn't work work because indices doesn't give the indices of each row... What's the best way to do this?


Edit:

def HblockDiag(H, idenRows):
    x = H.tocoo()
    idenRows = np.asarray(idenRows, dtype=x.row.dtype)
    x.row = idenRows[x.row]
    H = x.tocsr()
    return H

test = sps.csr_matrix([[1,2,4],[6,3,4],[8,5,2]])
print test.toarray()
test = HblockDiag(test, [2,0,1])
print test.toarray()

I get:

[[1 2 4]
 [6 3 4]
 [8 5 2]]
[[6 3 4]
 [8 5 2]
 [1 2 4]]

instead, I would like to get:

[[8 5 2]
 [1 2 4]
 [6 3 4]]
1
What is idenRows? Unless you understand the csr format, it is better to use indexing, rather trying to modify the attributes directly. - hpaulj
idenRows is a vector with the new orde of rows. So: [0,1,3,2] would swap rows 2 and 3. (that was just an example, idenRows is actually 256 elements long) - Jean-Luc
Just to be sure: is the desired result [[8 5 2], [1 2 4], [6 3 4]]? If so, please edit the question to include this. - unutbu

1 Answers

2
votes
  • Convert from CSR to COO format.

    x = Hz.tocoo()
    

    Per the doc string, sparse.coo_matrix.__doc__, COO has "very fast conversion to and from CSR/CSC formats".

  • Permute the rows of the COO matrix

    idenRows = np.argsort(idenRows)
    x.row = idenRows[x.row]
    
  • Convert from COO back to CSR

    Hz = x.tocsr()
    

For example,

import numpy as np
import scipy.sparse as sps

def HblockDiag(H, idenRows):
    x = H.tocoo()
    idenRows = np.argsort(idenRows)
    idenRows = np.asarray(idenRows, dtype=x.row.dtype)
    x.row = idenRows[x.row]
    H = x.tocsr()
    return H

test = sps.csr_matrix([[1,2,4],[6,3,4],[8,5,2]])
print test.toarray()
# [[1 2 4]
#  [6 3 4]
#  [8 5 2]]

test = HblockDiag(test, [2,0,1])
print test.toarray()

yields

[[8 5 2]
 [1 2 4]
 [6 3 4]]

PS. Generally, sparse matrices are used only when the size of the matrix is very large. It's not clear why you would want to use a sparse matrix if the shape is only (256, 256). Also, matrices should contain at least 80% zeros for sparse matrices to pay off.