Angenommen, ich konstruiere zwei Numpy-Arrays:
a = np.array([np.NaN, np.NaN])
b = np.array([np.NaN, np.NaN, 3])
Jetzt finde ich, dass np.mean
das nan
für beide zurückkehrt a
und b
:
>>> np.mean(a)
nan
>>> np.mean(b)
nan
Seit numpy 1.8 (veröffentlicht am 20. April 2016) sind wir mit nanmean gesegnet , das nan
Werte ignoriert :
>>> np.nanmean(b)
3.0
Wenn das Array jedoch nur nan
Werte enthält, wird eine Warnung ausgegeben:
>>> np.nanmean(a)
nan
C:\python-3.4.3\lib\site-packages\numpy\lib\nanfunctions.py:598: RuntimeWarning: Mean of empty slice
warnings.warn("Mean of empty slice", RuntimeWarning)
Ich mag es nicht, Warnungen zu unterdrücken. Gibt es eine bessere Funktion, mit der ich das Verhalten nanmean
ohne diese Warnung ermitteln kann?
nan
; die andere, um konsequent eine Ausnahme auszulösen. Eine Warnung ist eine solche Antwort.np.nanmean
Stil tun - unterdrücken Sie einfach die Warnung, wenn Sie wissen, dass Sie sie für ein Array aller NaNs verwenden könnten.nanmean
- Sie bekommen das gleiche dumme Ding mitnp.mean([])
.Antworten:
Ich sehe wirklich keinen guten Grund, die Warnung nicht einfach zu unterdrücken.
Am sichersten ist es, den
warnings.catch_warnings
Kontextmanager zu verwenden, um die Warnung nur dort zu unterdrücken, wo Sie sie erwarten. Auf diese Weise verpassen Sie keine zusätzlichen Warnungen,RuntimeWarnings
die in einem anderen Teil Ihres Codes unerwartet ausgelöst werden könnten:import numpy as np import warnings x = np.ones((1000, 1000)) * np.nan # I expect to see RuntimeWarnings in this block with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) foo = np.nanmean(x, axis=1)
Die Lösung von @ dawg würde auch funktionieren, aber letztendlich verursachen alle zusätzlichen Schritte, die Sie ausführen müssen, um die Berechnung
np.nanmean
auf einem Array aller NaNs zu vermeiden, zusätzlichen Aufwand, den Sie vermeiden könnten, indem Sie nur die Warnung unterdrücken. Auch Ihre Absicht wird sich viel deutlicher im Code widerspiegeln.quelle
seterr
dafür wie andere Fehlerwarnings.filterwarnings(action='ignore', message='Mean of empty slice')
scheint sicherer zu sein, da andereRuntimeWarning
, die Sie nicht erwartet haben, nicht ignoriert werden .Ein
NaN
Wert ist so definiert, dass er nicht gleich sich selbst ist:>>> float('nan') == float('nan') False >>> np.NaN == np.NaN False
Sie können eine Python-Bedingung verwenden und die Eigenschaft eines Nan niemals gleich sein, um dieses Verhalten zu erhalten:
>>> a = np.array([np.NaN, np.NaN]) >>> b = np.array([np.NaN, np.NaN, 3]) >>> np.NaN if np.all(a!=a) else np.nanmean(a) nan >>> np.NaN if np.all(b!=b) else np.nanmean(b) 3.0
Sie können auch tun:
import warnings import numpy as np a = np.array([np.NaN, np.NaN]) b = np.array([np.NaN, np.NaN, 3]) with warnings.catch_warnings(): warnings.filterwarnings('error') try: x=np.nanmean(a) except RuntimeWarning: x=np.NaN print x
quelle
np.nanmean(np.array([[np.NaN], [3]]),1)
np.nanmean(np.array([[np.NaN], [3]]),1)
scheint wie erwartet zu funktionieren ...try
/except
Block verwenden?np.nanmean(a)
werdenp.nan
trotzdem zurückkehren.try / except
Block zu setzen , da anderer Python-Code für etwas wäre, das sich von der normalen Rückgabe unterscheiden könnte.np.nan
wäre die Rückgabe eines Skalarsnp.nanmean
entlang einer Achse eines mehrdimensionalen Arrays, das nur NaNs enthält, falsch