Conditional indexing with Numpy ndarray Conditional indexing with Numpy ndarray numpy numpy

Conditional indexing with Numpy ndarray


For a numpy based solution, you can use numpy.where and then get the row indexes from it and then use it for indexing you matrix. Example -

matrix[np.where((1 <= matrix[:,0]) & (matrix[:,0] <= 6)       & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))]

Demo -

In [169]: matrixOut[169]:array([[  1.,   2.,   3.,   4.,   5.],       [  6.,   7.,   8.,   9.,  10.],       [ 11.,  12.,  13.,  14.,  15.],       [ 16.,  17.,  18.,  19.,  20.]])In [170]: matrix[np.where((1 <= matrix[:,0]) & (matrix[:,0] <= 6)   .....:        & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))]Out[170]:array([[  1.,   2.,   3.,   4.,   5.],       [  6.,   7.,   8.,   9.,  10.]])

Another method , as indicated in the comments would be to use boolean masks, Example -

mask = ((1 <= matrix[:,0]) & (matrix[:,0] <= 6)           & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))matrix[mask,:]

Demo -

In [41]: matrixOut[41]:array([[  1.,   2.,   3.,   4.,   5.],       [  6.,   7.,   8.,   9.,  10.],       [ 11.,  12.,  13.,  14.,  15.],       [ 16.,  17.,  18.,  19.,  20.]])In [42]: mask = ((1 <= matrix[:,0]) & (matrix[:,0] <= 6)   ....:            & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))In [43]:In [43]: matrix[mask,:]Out[43]:array([[  1.,   2.,   3.,   4.,   5.],       [  6.,   7.,   8.,   9.,  10.]])


You can get the indices with :

rows = np.logical_and(0 < matrix[:, 0], < matrix[:, 0] < 6 ) *  np.logical_and(1 < matrix[:, 1], matrix[:, 1] < 7)

Then newMatrix = np.delete(matrix, rows, axis = 0)


You mentioned MATLAB. Here's the equivalent to the accepted answer using Octave

octave:17> ma=reshape(1:20,5,4)ma =    1    6   11   16    2    7   12   17    3    8   13   18    4    9   14   19    5   10   15   20octave:18> mask=(1<=ma(1,:))&(ma(1,:)<=6)&(2<=ma(2,:))&(ma(2,:)<=7)mask =   1   1   0   0octave:19> ma(:,mask)ans =    1    6    2    7    3    8    4    9    5   10

The accepted answer without where is:

In [592]: mask=(1 <= matrix[:,0]) & (matrix[:,0] <= 6) &(2 <= matrix[:,1]) & (matrix[:,1] <= 7)In [593]: matrix[mask,:]Out[593]: array([[  1.,   2.,   3.,   4.,   5.],       [  6.,   7.,   8.,   9.,  10.]])

I switched rows and columns in the Octave version because that is its natural way of generating the same numbers (MATLAB/Octave use the equivalent of numpys 'F' order - see below).

The other changes are 0 v 1 start index, and () v []. Otherwise the two notations are similar.

A simpler way to generate the matrix in numpy:

In [594]: np.arange(1,21).reshape(4,5)Out[594]: array([[ 1,  2,  3,  4,  5],       [ 6,  7,  8,  9, 10],       [11, 12, 13, 14, 15],       [16, 17, 18, 19, 20]])

Or with the MATLAB layout:

In [595]: np.arange(1,21).reshape(5,4,order='F')Out[595]: array([[ 1,  6, 11, 16],       [ 2,  7, 12, 17],       [ 3,  8, 13, 18],       [ 4,  9, 14, 19],       [ 5, 10, 15, 20]])