2010-12-19 4 views
15

Ich habe ein NxM-Array in numpy, für das ich das Protokoll aufnehmen möchte, und ignoriere Einträge, die vor der Protokollierung negativ waren. Wenn ich das Protokoll von negativen Einträgen nehme, gibt es -Inf zurück, also werde ich eine Matrix mit einigen -Inf-Werten als Ergebnis haben. Ich möchte dann die Spalten dieser Matrix summieren, aber die -Inf-Werte ignorieren - wie kann ich das tun?Ignorieren von -Inf-Werten in Arrays mit numpy/scipy in Python

Zum Beispiel

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

Ich weiß, dass es nansum und ich brauche das Äquivalent, so etwas wie infsum.

Danke.

Antwort

10

Verwendung 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

Kannst du das bitte weiter ausführen? Ich verstehe das Beispiel nicht. Wie haben Sie das maskierte Array oben initialisiert? – user248237dfsf

+3

@ user248237 - Die Funktionen 'numpy.ma.log' usw. erzeugen automatisch ein maskiertes Array, in dem alles, was zu einem 'inf' oder 'nan' führt, maskiert wird. Dies ist jedoch etwas weniger explizit, so dass Sie stattdessen Folgendes tun können: 'a = np.ma.masked_where (a == np.inf, a)', und dann einfach 'b = np.log (a) ' (oder irgendeine andere Funktion). Alternativ können Sie maskierte Arrays vermeiden und einfach 'np.log (a [a! = Np.inf]). Sum()' (Sie können mit booleschen Arrays indizieren, es ist viel sauberer und schneller als das 'filter'-basierte Antworten.) –

+0

@ user248237 Ich habe das maskierte Array nicht explizit initialisiert. 'a' ist nur ein normales, nicht maskiertes Array. 'ma.log' maskiert alle Werte, bei denen der (reale) Logarithmus nicht definiert ist. Dann wird das resultierende maskierte Array "b" grob behandelt, als ob die maskierten Einträge nicht vorhanden wären. – Philipp

1

Verwenden Sie ein filter():

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

Wird dies als vektorisierte Operation betrachtet? Gibt es einen effizienteren Weg? Ich muss dies oft in meinem Code tun und wollte einen vektorisierten Ansatz – user248237dfsf

+0

Fragen Sie, ob dies in-Place mit Iteratoren getan wird? Nein. Gibt es einen effizienteren Weg? AFAIK, Sie müssten das Array durchlaufen, da es keine Filterfunktion gibt, die einen Iterator zurückgibt, außer Sie schreiben einen. – marcog

+0

Ich glaube nicht, dass der Filtercode für NxM-Arrays funktioniert. Es scheint nur für 1xM-Vektoren zu funktionieren. – user248237dfsf

1

vielleicht können Sie indizieren Ihre Matrix und Verwendung:

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

Der einfachste Weg dies zu tun ist, zu verwenden, numpy.ma.masked_invalid():

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