2011-05-11 15 views
6

Consideremos el siguiente código numpy:numpy: booleano indexación y el uso de memoria

A[start:end] = B[mask] 

aquí:

  • A y B son matrices 2D con el mismo número de columnas;
  • start y end son escalares;
  • mask es una matriz booleana 1D;
  • (end - start) == sum(mask).

En principio, la operación anterior se puede llevar a cabo utilizando O(1) almacenamiento temporal, copiando elementos de B directamente en A.

¿Esto es realmente lo que sucede en la práctica, o numpy construye una matriz temporal para B[mask]? Si es este último, ¿hay alguna forma de evitar esto reescribiendo el enunciado?

Respuesta

2

El uso de matrices booleanas como índice es una indexación sofisticada, por lo que numpy necesita hacer una copia. Podrías escribir una extensión cython para manejarlo, si tienes problemas de memoria.

+0

+1 para traer Cython. Es este tipo de bucles que sobresale en. –

3

La línea

A[start:end] = B[mask] 

será - según la definición del lenguaje Python - evaluar primero el lado derecho, produciendo una nueva matriz que contiene las filas seleccionadas de B y ocupando memoria adicional. La forma más pura de Python más eficiente Soy consciente de evitar esto es utilizar un bucle explícito:

from itertools import izip, compress 
for i, b in izip(range(start, end), compress(B, mask)): 
    A[i] = b 

Por supuesto, esto será mucho menos eficiente en el tiempo de su código original, pero sólo usa O (1) memoria adicional. También tenga en cuenta que itertools.compress() está disponible en Python 2.7 o 3.1 o superior.

+1

Seguramente, "producir una nueva matriz que contiene las filas seleccionadas de B y ocupar memoria adicional" es un non sequitur? Depende de 'B .__ getitem __()' para elegir lo que quiere devolver. Por ejemplo, si 'mask' fuera un' slice', se devolvería un proxy (vista) y no se realizaría ninguna copia. – NPE

+0

@aix: según el OP, 'mask' es una matriz booleana unidimensional. ¿Yo me perdí algo? –

+0

@aix: Oh, ya veo. La parte con la definición de idioma es un poco ambigua. Solo se refería a la parte "primero evaluar el lado derecho". –