Set last non-zero element of each row to zero - NumPy
<p>I have an array A:</p>

<pre><code>A = array([[1, 2, 3,4], [5,6,7,0] , [8,9,0,0]])
</code></pre>

<p>I want to change the last non-zero of each row to 0 </p>

<pre><code>A = array([[1, 2, 3,0], [5,6,0,0] , [8,0,0,0]])
</code></pre>

<p>how to write the code for any n*m  numpy array?
Thanks, S ;-)</p>

<p><strong>Approach #1</strong></p>

<p>One approach based on <code>cumsum</code> and <code>argmax</code> -</p>

<pre><code>A[np.arange(A.shape[0]),(A!=0).cumsum(1).argmax(1)] = 0
</code></pre>

<p>Sample run -</p>

<pre><code>In [59]: A
Out[59]: 
array([[2, 0, 3, 4],
       [5, 6, 7, 0],
       [8, 9, 0, 0]])

In [60]: A[np.arange(A.shape[0]),(A!=0).cumsum(1).argmax(1)] = 0

In [61]: A
Out[61]: 
array([[2, 0, 3, 0],
       [5, 6, 0, 0],
       [8, 0, 0, 0]])
</code></pre>

<p><strong>Approach #2</strong></p>

<p>One more based on <code>argmax</code> and hopefully more efficient -</p>

<pre><code>A[np.arange(A.shape[0]),A.shape[1] - 1 - (A[:,::-1]!=0).argmax(1)] = 0
</code></pre>

<hr>

<p><strong>Explanation</strong></p>

<p>One of the uses of <code>argmax</code> is to get ID  of the <strong>first</strong> occurence of the <code>max</code> element along an axis in an array . In the first approach we get the cumsum along the rows and get the first max ID, which represents the last non-zero elem. This is because <code>cumsum</code> on the leftover elements won't increase the sum value after that last non-zero element. </p>

<p>Let's re-run that case in a bit more detailed manner -</p>

<pre><code>In [105]: A
Out[105]: 
array([[2, 0, 3, 4],
       [5, 6, 7, 0],
       [8, 9, 0, 0]])

In [106]: (A!=0)
Out[106]: 
array([[ True, False,  True,  True],
       [ True,  True,  True, False],
       [ True,  True, False, False]], dtype=bool)

In [107]: (A!=0).cumsum(1)
Out[107]: 
array([[1, 1, 2, 3],
       [1, 2, 3, 3],
       [1, 2, 2, 2]])

In [108]: (A!=0).cumsum(1).argmax(1)
Out[108]: array([3, 2, 1])
</code></pre>

<p>Finally, we use <code>fancy-indexing</code> to use those as the column indices to set appropriate elements in <code>A</code>.</p>

<p>In the second approach, when we use <code>argmax</code> on the boolean array, we simply got the first occurence of <code>True</code>, which we used on a row-flipped version of the input array. As such, we would have the last non-zero elem in the original order. Rest of the idea there, is the same.</p>

python numpy theano