2010-12-19 24 views
15

Tengo una matriz NxM en numpy de la que me gustaría tomar el registro, e ignoro las entradas que fueron negativas antes de tomar el registro. Cuando tomo el registro de entradas negativas, devuelve -Inf, así que tendré una matriz con algunos valores -Inf como resultado. Luego quiero resumir las columnas de esta matriz, pero ignorando los valores de -Inf, ¿cómo puedo hacer esto?Ignorando -Inf valores en matrices utilizando numpy/scipy en Python

Por ejemplo,

mylogarray = log(myarray) 
# take sum, but ignore -Inf? 
sum(mylogarray, 0) 

Sé que hay nansum y necesito el equivalente, algo así como infsum.

Gracias.

Respuesta

10

Uso masked arrays:

>>> a = numpy.array([2, 0, 1.5, -3]) 
>>> b = numpy.ma.log(a) 
>>> b 
masked_array(data = [0.69314718056 -- 0.405465108108 --], 
      mask = [False True False True], 
     fill_value = 1e+20) 

>>> b.sum() 
1.0986122886681096 
+1

¿puede por favor ampliar esto? No entiendo el ejemplo. ¿Cómo inicializaste la matriz enmascarada de arriba? – user248237dfsf

+3

@ user248237 - Las funciones 'numpy.ma.log', etc, crearán automáticamente una matriz enmascarada en la que se enmascara todo lo que da como resultado un' inf' o 'nan'. Sin embargo, esto es un poco menos explícito, por lo que puede hacer esto: 'a = np.ma.masked_where (a == np.inf, a)', y luego simplemente 'b = np.log (a)' (o cualquier otra función). Alternativamente, puede evitar matrices enmascaradas y simplemente hacer 'np.log (a [a! = Np.inf]). Sum()' (Puede indexar por matrices booleanas, es mucho más limpio y más rápido que el basado en 'filtro' respuestas.) –

+0

@ user248237 No inicialicé la matriz enmascarada explícitamente. 'a' es solo una matriz normal, no enmascarada. 'ma.log' enmascara todos los valores donde el logaritmo (real) no está definido. Entonces, la matriz enmascarada resultante 'b' se trata aproximadamente como si las entradas enmascaradas no estuvieran allí. – Philipp

1

Utilice un filter():

>>> array 
array([ 1., 2., 3., -Inf]) 
>>> sum(filter(lambda x: x != float('-inf'), array)) 
6.0 
+0

¿Esto se considera una operación vectorizada? ¿Hay una manera más eficiente? Necesito hacer esto muchas veces en mi código y quería un enfoque vectorizado – user248237dfsf

+0

¿Me está preguntando si esto se hace in situ con los iteradores? No. ¿Hay una manera más eficiente? AFAIK, tendrías que recorrer la matriz ya que no hay función de filtro que devuelva un iterador, a menos que escribas uno. – marcog

+0

No creo que el código de filtro funcione para arreglos NxM ... parece que solo funciona para vectores 1xM. – user248237dfsf

1

tal vez usted puede indexar su matriz y uso:

import numpy as np; 
matrix = np.array([[1.,2.,3.,np.Inf],[4.,5.,6.,np.Inf],[7.,8.,9.,np.Inf]]); 
print matrix[:,1]; 
print sum(filter(lambda x: x != np.Inf,matrix[:,1])); 
print matrix[1,:]; 
print sum(filter(lambda x: x != np.Inf,matrix[1,:])); 
15

La forma más sencilla de hacerlo es utilizar numpy.ma.masked_invalid():

a = numpy.log(numpy.arange(15)) 
a.sum() 
# -inf 
numpy.ma.masked_invalid(a).sum() 
# 25.19122118273868 
Cuestiones relacionadas