2012-09-15 9 views
7

Dada una matriz numpy 2D, es decir;Modificar la sección de matriz numpy in situ usando indexación booleana

import numpy as np 

data = np.array([ 
    [11,12,13], 
    [21,22,23], 
    [31,32,33], 
    [41,42,43],   
    ]) 

Necesito modificar en su lugar una sub-matriz basada en dos vectores de enmascaramiento para las filas y columnas deseadas;

rows = np.array([False, False, True, True], dtype=bool) 
cols = np.array([True, True, False], dtype=bool) 

Tales that i.e .;

print data 

#[[11,12,13], 
# [21,22,23], 
# [0,0,33], 
# [0,0,43]]  

Respuesta

5

Now que ya sabe cómo acceder a las filas/cols usted quiere, apenas cedida el valor que desee a su subconjunto. Es un poco más complicado, sin embargo:

mask = rows[:,None]*cols[None,:] 
data[mask] = 0 

La razón es que cuando se accede a la submatriz como data[rows][:,cols] (como se ilustra en su previous question, estamos tomando una vista de una vista, y algunas referencias a los datos originales llegar perdido en el camino.

en cambio, aquí se construye una matriz booleana 2D mediante la difusión de sus dos matrices 1D rows y cols uno con el otro. Su gama mask tiene ahora la forma (len(rows),len(cols). podemos utilizar mask para acceder directamente al original artículos de data, y los establecemos en un nuevo valor. cuando haces data[mask], obtienes una matriz 1D, que no era la respuesta que querías en tu previous question.

Para construir la máscara, que podría haber utilizado el operador & en lugar de * (ya que estamos tratando con matrices booleanas), o el simple np.outer función:

mask = np.outer(rows,cols) 

Editar: apoyos a @Marcus Jones para la solución np.outer.

+1

Hace el trabajo, pero ¿qué tal "mask = np.outer (rows, cols)"? –

+1

¿Hay alguna forma de obtener una vista de la indexación booleana? Lo anterior funciona solo porque numpy trata la asignación de manera diferente. 'data [mask]' aún no es una vista. –

Cuestiones relacionadas