Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - NumPy - deleting multiple rows and columns from an array

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.

like image 926
tommy.carstensen Avatar asked Apr 25 '15 11:04

tommy.carstensen


2 Answers

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])
like image 38
rth Avatar answered Oct 07 '22 17:10

rth


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
like image 95
Bas Swinckels Avatar answered Oct 07 '22 16:10

Bas Swinckels