Let's say I have a square matrix as input:
array([[0, 1, 1, 0],
[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 1, 1, 0]])
I want to count the nonzeros in the array after removal of rows 2 and 3 and cols 2 and 3. Afterwards I want to do the same for rows 3 and 4 and cols 3 and 4. Hence the output should be:
0 # when removing rows/cols 2 and 3
3 # when removing rows/cols 3 and 4
Here is the naive solution using np.delete
:
import numpy as np
a = np.array([[0,1,1,0],[1,1,1,1],[1,1,1,1],[0,1,1,0]])
np.count_nonzero(np.delete(np.delete(a, (1,2), axis=0), (1,2), axis=1))
np.count_nonzero(np.delete(np.delete(a, (2,3), axis=0), (2,3), axis=1))
But np.delete
returns a new array. Is there a faster method, which involves deleting rows and columns simultaneously? Can masking be used? The documentation on np.delete
reads:
Often it is preferable to use a boolean mask.
How do I go about doing that? Thanks.
There is no need to modify your original array by deleting rows/columns, in order to count the number of non zero elements. Simply use indexing,
a = np.array([[0,1,1,0],[1,1,1,1],[1,1,1,1],[0,1,1,0]])
irows, icols = np.indices(a.shape)
mask = (irows!=2)&(irows!=3)&(icols!=2)&(icols!=3)
np.count_nonzero(a[mask])
Instead of deleting the columns and rows you don't want, it is easier to select the ones you do want. Also note that it is standard to start counting rows and columns from zeros. To get your first example, you thus want to select all elements in rows 0 and 3 and in rows 0 and 3. This requires advanced indexing, for which you can use the ix_ utility function:
In [25]: np.count_nonzero(a[np.ix_([0,3], [0,3])])
Out[25]: 0
For your second example, you want to select rows 0 and 1 and columns 0 and 1, which can be done using basic slicing:
In [26]: np.count_nonzero(a[:2,:2])
Out[26]: 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With