I have a sparse csr_matrix, and I want to change the values of a single row to different values. I can't find an easy and efficient implementation however. This is what it has to do:
A = csr_matrix([[0, 1, 0],
[1, 0, 1],
[0, 1, 0]])
new_row = np.array([-1, -1, -1])
print(set_row_csr(A, 2, new_row).todense())
>>> [[ 0, 1, 0],
[ 1, 0, 1],
[-1, -1, -1]]
This is my current implementation of set_row_csr
:
def set_row_csr(A, row_idx, new_row):
A[row_idx, :] = new_row
return A
But this gives me a SparseEfficiencyWarning
. Is there a way of getting this done without manual index juggling, or is this my only way out?
In physicalattraction's answer, the
len(new_row)
must be equal toA.shape[1]
what may not be interesting when adding sparse rows.So, based on his answer I've came up with a method to set rows in csr while it keeps the sparcity property. Additionally I've added a method to convert dense arrays to sparse arrays (on data, indices format)
physicalattraction's answer is indeed significantly quicker. It's much faster than my solution, which was to just add a separate matrix with that single row set. Though the addition solution was faster than the slicing solution.
The take away for me is that the fastest way to set rows in a csr_matrix or columns in a csc_matrix is to modify the underlying data yourself.
The slice solution also scales much worse with the size and sparsity of the matrix.
In the end, I managed to get this done with index juggling.
Something is wrong with this
set_row_csr
. Yes, it is fast and it seemed to work for some test cases. However, it seems to garble the internal csr structure of the csr sparse matrix in my test cases. Trylil_matrix(A)
afterwards and you will see error messages.