scipy.sparse matrix: subtract row mean to nonzero elements
<p>I have a sparse matrix in <a href="http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csr_matrix.html" rel="nofollow">csr_matrix</a> format. For each row i need to subtract row mean from the nonzero elements. The means must be computed on the number of the nonzero elements of the row (instead of the length of the row).
I found a fast way to compute the row means with the following code:</p>

<pre><code># M is a csr_matrix
sums = np.squeeze(np.asarray(M.sum(1)))    # sum of the nonzero elements, for each row
counts = np.diff(M.tocsr().indptr)         # count of the nonzero elements, for each row


# for the i-th row the mean is just sums[i] / float(counts[i]) 
</code></pre>

<p>The problem is the updates part. I need a fast way to do this.
Actually what i am doing is to transform M to a <a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html" rel="nofollow">lil_matrix</a> and perform the updates in this way:</p>

<pre><code>M = M.tolil()

for i in xrange(len(sums)):
    for j in M.getrow(i).nonzero()[1]:
        M[i, j] -= sums[i] / float(counts[i])
</code></pre>

<p>which is slow. Any suggestion for a faster solution?</p>

<p>Starting with <code>@Dthal's</code> sample:</p>

<pre><code>In [92]: a = sparse.csr_matrix([[1.,0,2],[1,2,3]])
In [93]: a.A
Out[93]: 
array([[ 1.,  0.,  2.],
       [ 1.,  2.,  3.]])

In [94]: sums=np.squeeze(a.sum(1).A)
# sums=a.sum(1).A1   # shortcut
In [95]: counts=np.diff(a.tocsr().indptr)
In [96]: means=sums/counts
In [97]: sums
Out[97]: array([ 3.,  6.])
In [98]: counts
Out[98]: array([2, 3], dtype=int32)
In [99]: means
Out[99]: array([ 1.5,  2. ])
</code></pre>

<p><code>repeat</code> lets us replicate the <code>means</code>, producing an array that matches the matrix <code>data</code> in size.</p>

<pre><code>In [100]: mc = np.repeat(means, counts)
In [101]: mc
Out[101]: array([ 1.5,  1.5,  2. ,  2. ,  2. ])
</code></pre>

<p>This <code>mc</code> is the same as <code>@Dthal's</code> <code>(b*d).data</code>.</p>

<p>Now just subtract it from <code>data</code>.</p>

<pre><code>In [102]: a.data -= mc
In [103]: a.A
Out[103]: 
array([[-0.5,  0. ,  0.5],
       [-1. ,  0. ,  1. ]])
</code></pre>

python scipy updates sparse-matrix mean