可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Say I construct two numpy arrays:
a = np.array([np.NaN, np.NaN]) b = np.array([np.NaN, np.NaN, 3])
Now I find that np.mean
returns nan
for both a
and b
:
>>> np.mean(a) nan >>> np.mean(b) nan
Since numpy 1.8 (released 20 April 2016), we've been blessed with nanmean
, which ignores nan
values:
>>> np.nanmean(b) 3.0
However, when the array has nothing but nan
values, it raises a warning:
>>> 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)
I don't like suppressing warnings; is there a better function I can use to get the behaviour of nanmean
without that warning?
回答1:
I really can't see any good reason not to just suppress the warning.
The safest way would be to use the warnings.catch_warnings
context manager to suppress the warning only where you anticipate it occurring - that way you won't miss any additional RuntimeWarnings
that might be unexpectedly raised in some other part of your code:
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)
@dawg's solution would also work, but ultimately any additional steps that you have to take in order to avoid computing np.nanmean
on an array of all NaNs are going to incur some extra overhead that you could avoid by just suppressing the warning. Also your intent will be much more clearly reflected in the code.
回答2:
A NaN
value is defined to not be equal to itself:
>>> float('nan') == float('nan') False >>> np.NaN == np.NaN False
You can use a Python conditional and the property of a nan never being equal to itself to get this behavior:
>>> 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
You can also do:
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