2010-10-04 21 views
6

Tengo un código que intenta encontrar el contenido de una matriz en índices especificados por otra, que puede especificar índices que están fuera del alcance de la matriz anterior.Indexación con matrices enmascaradas en numpy

input = np.arange(0, 5) 
indices = np.array([0, 1, 2, 99]) 

Lo que quiero hacer es esto: de entrada de impresión [índices] y obtener [0 1 2]

Pero esto produce una excepción (como se esperaba):

IndexError: index 99 out of bounds 0<=index<5 

Así que pensé que podría usar matrices enmascaradas para ocultar los índices de fuera de límites:

indices = np.ma.masked_greater_equal(indices, 5) 

Pero aún así:

>print input[indices] 
IndexError: index 99 out of bounds 0<=index<5 

A pesar de que:

>np.max(indices) 
2 

Así que estoy tener que llenar la matriz de máscaras en primer lugar, lo cual es molesto, ya que no sé qué llenar valor que podría utilizar no seleccionar ningún índices para los que están fuera de rango:

de entrada de impresión [np.ma.filled (índices, 0)]

[0 1 2 0] 

Así que mi pregunta es: ¿cómo se puede utilizar numpy de manera eficiente para seleccionar índices de forma segura desde una matriz sin sobrepasar los límites de la matriz de entrada?

Respuesta

5

Sin utilizar matrices enmascarados, usted podría quitar los índices de mayor o igual a 5 así:

print input[indices[indices<5]] 

Editar: tenga en cuenta que si también quería descartar índices negativos, se podría escribir:

print input[indices[(0 <= indices) & (indices < 5)]] 
+0

D'oh eso funciona. Todavía tengo curiosidad sobre por qué no podemos usar correctamente matrices enmascaradas para la indexación, pero supongo que en realidad no importa. – Widjet

3

Es una MUY mala idea indexar con matrices enmascaradas. Hubo un tiempo (muy corto) con el uso de MaskedArrays para la indexación habría arrojado una excepción, pero fue un poco duro ...

En su prueba, está filtrando indices para encontrar las entradas que coincidan con una condición. ¿Qué deberías hacer con las entradas faltantes de tu MaskedArray? ¿La condición es falsa? Cierto ? ¿Deberías usar un valor predeterminado? Depende de usted, el usuario, decidir qué hacer.

El uso de indices.filled(0) significa que cuando un elemento de indices está enmascarado (como en, sin definir), desea tomar el primer índice (0) como predeterminado. Probablemente no sea lo que querías.

Aquí, simplemente habría usado input[indices.compressed()]: el método compressed aplana su MaskedArray, manteniendo sólo las entradas sin máscara.

Pero como te diste cuenta, probablemente no necesitaras MaskedArrays en primer lugar

+0

'comprimido' era lo que buscaba, gracias. Había asumido que el uso de matrices enmascaradas para indexar los comprimiría en primer lugar, lo que parece un error razonable. Pero supongo que eso probablemente requeriría asignar una nueva matriz, lo que representaría un costoso incumplimiento. – Widjet