¿Cómo enmascarar adecuadamente una matriz 2D numpy?

Digamos que tengo una matriz bidimensional de coordenadas que parece algo así como

x = array([[1,2],[2,3],[3,4]])

Anteriormente en mi trabajo hasta ahora, generé una máscara que termina pareciendo algo así como

mask = [False,False,True]

Cuando bash usar esta máscara en el vector de coordenadas 2D, aparece un error

 newX = np.ma.compressed(np.ma.masked_array(x,mask)) >>>numpy.ma.core.MaskError: Mask and data not compatible: data size is 6, mask size is 3.` 

Lo que tiene sentido, supongo. Así que intenté simplemente usar la siguiente máscara en su lugar:

 mask2 = np.column_stack((mask,mask)) newX = np.ma.compressed(np.ma.masked_array(x,mask2)) 

Y lo que obtengo está cerca:

>>>array([1,2,2,3])

a lo que yo esperaría (y querría):

>>>array([[1,2],[2,3]])

Debe haber una manera más fácil de hacer esto?

¿Es esto lo que estás buscando?

 import numpy as np x[~np.array(mask)] # array([[1, 2], # [2, 3]]) 

O de la matriz enmascarada numpy :

 newX = np.ma.array(x, mask = np.column_stack((mask, mask))) newX # masked_array(data = # [[1 2] # [2 3] # [-- --]], # mask = # [[False False] # [False False] # [ True True]], # fill_value = 999999) 

Tu x es 3×2:

 In [379]: x Out[379]: array([[1, 2], [2, 3], [3, 4]]) 

Haz una máscara booleana de 3 elementos:

 In [380]: rowmask=np.array([False,False,True]) 

Se puede usar para seleccionar las filas donde es verdadero o donde es falso. En ambos casos el resultado es 2d:

 In [381]: x[rowmask,:] Out[381]: array([[3, 4]]) In [382]: x[~rowmask,:] Out[382]: array([[1, 2], [2, 3]]) 

Esto es sin usar la subclase MaskedArray. Para hacer dicha matriz, necesitamos una máscara que coincida con x en forma. No hay provisión para enmascarar una sola dimensión.

 In [393]: xmask=np.stack((rowmask,rowmask),-1) # column stack In [394]: xmask Out[394]: array([[False, False], [False, False], [ True, True]], dtype=bool) In [395]: np.ma.MaskedArray(x,xmask) Out[395]: masked_array(data = [[1 2] [2 3] [-- --]], mask = [[False False] [False False] [ True True]], fill_value = 999999) 

La aplicación compressed produce una matriz enraizada: array([1, 2, 2, 3])

Como el enmascaramiento es elemento por elemento, podría enmascarar un elemento en la fila 1, 2 en la fila 2, etc. Por lo tanto, al compressing , eliminar los elementos enmascarados, no se obtendrá una matriz 2D. La forma aplanada es la única opción general.

np.ma tiene más sentido cuando hay una dispersión de valores enmascarados. No tiene mucho valor si desea seleccionar, o deseleccionar, filas o columnas completas.

===============

Aquí hay arrays enmascarados más típicos:

 In [403]: np.ma.masked_inside(x,2,3) Out[403]: masked_array(data = [[1 --] [-- --] [-- 4]], mask = [[False True] [ True True] [ True False]], fill_value = 999999) In [404]: np.ma.masked_equal(x,2) Out[404]: masked_array(data = [[1 --] [-- 3] [3 4]], mask = [[False True] [ True False] [False False]], fill_value = 2) In [406]: np.ma.masked_outside(x,2,3) Out[406]: masked_array(data = [[-- 2] [2 3] [3 --]], mask = [[ True False] [False False] [False True]], fill_value = 999999) 

Como ninguna de estas soluciones funcionó para mí, pensé en escribir qué solución hizo, tal vez sea útil para alguien más. Uso python 3.x y trabajé en dos arreglos 3D. Uno, al que llamo data_3D contiene valores flotantes de grabaciones en un escáner cerebral, y el otro, template_3D contiene números enteros que representan regiones del cerebro. Quería elegir esos valores de data_3D correspondientes a un region_code entero según template_3D :

 my_mask = np.in1d(template_3D, region_code).reshape(template_3D.shape) data_3D_masked = data_3D[my_mask] 

lo que me da una matriz 1D de grabaciones relevantes solamente.

En tu último ejemplo, el problema no es la máscara. Es su uso de compressed . De la documentación de compressed :

 Return all the non-masked data as a 1-D array. 

Así compressed aplana los valores no enmascarados en una matriz 1-d. (Tiene que hacerlo, porque no hay garantía de que los datos comprimidos tengan una estructura n-dimensional).

Echa un vistazo a la matriz enmascarada antes de comprimirlo:

 In [8]: np.ma.masked_array(x, mask2) Out[8]: masked_array(data = [[1 2] [2 3] [-- --]], mask = [[False False] [False False] [ True True]], fill_value = 999999)