Indexación condicional con numpray numpy

Tengo una matriz de ndarray Numpy de valores flotantes y debo seleccionar filas específicas donde ciertas columnas tienen valores que satisfacen ciertos criterios. Por ejemplo, digamos que tengo la siguiente matriz numpy:

matrix = np.ndarray([4, 5]) matrix[0,:] = range(1,6) matrix[1,:] = range(6,11) matrix[2,:] = range(11,16) matrix[3,:] = range(16,21) 

Digamos que quiero seleccionar filas de la matriz donde el valor de la primera columna está entre 1 y 6 y el valor de la segunda columna está entre 2-7.

¿Cómo puedo obtener los índices de fila de la matriz donde se cumplen estas condiciones? ¿Qué pasa si quiero eliminar las filas que satisfacen el criterio condicional?

Para una solución basada en números, puede usar numpy.where y luego obtener los índices de las filas y luego usarla para indexar su matriz. Ejemplo –

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

Demo

 In [169]: matrix Out[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.]]) 

Otro método, como se indica en los comentarios, sería usar máscaras booleanas, Ejemplo -

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

Demo

 In [41]: matrix Out[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.]]) 

Puede obtener los índices con:

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

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

Usted mencionó MATLAB. Aquí está el equivalente a la respuesta aceptada usando 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 20 octave:18> mask=(1<=ma(1,:))&(ma(1,:)<=6)&(2<=ma(2,:))&(ma(2,:)<=7) mask = 1 1 0 0 octave:19> ma(:,mask) ans = 1 6 2 7 3 8 4 9 5 10 

La respuesta aceptada sin where es:

 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.]]) 

Cambié las filas y las columnas en la versión de Octave porque esa es su forma natural de generar los mismos números (MATLAB / Octave usa el equivalente de la numpy 'F' de numpy - vea a continuación).

Los otros cambios son 0 v 1 índice de inicio y () v []. De lo contrario las dos notaciones son similares.

Una forma más sencilla de generar la matrix en números:

 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]]) 

O con el diseño de MATLAB:

 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]]) 

Obtener índices de fila:

 row_indices = [x for x in range(4) if matrix[x][0] in range(1,7) and matrix[x][1] in range(2,8)] 

Eliminar filas:

 indices = [x for x in range(4) if not( matrix[x][0] in range(1,7) and matrix[x][1] in range(2,8))] new_matrix = matrix[indices]