mean, nanmean and warning: Mean of empty slice

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

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     


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!