mean、nanmean 和 warning:空切片的平均值

mean, nanmean and warning: Mean of empty slice

假设我构建了两个 numpy 数组:

a = np.array([np.NaN, np.NaN])
b = np.array([np.NaN, np.NaN, 3])

现在我发现 np.mean returns nan 对于 ab:

>>> np.mean(a)
nan
>>> np.mean(b)
nan

自 numpy 1.8(2016 年 4 月 20 日发布)以来,我们得到了 nanmean 的祝福,它忽略了 nan 值:

>>> np.nanmean(b)
3.0

但是,当数组没有 nan 值时,它会引发警告:

>>> 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)

我不喜欢抑制警告;有没有更好的函数我可以用来在没有警告的情况下获得 nanmean 的行为?

一个NaN值被定义为不等于它自己:

>>> float('nan') == float('nan')
False
>>> np.NaN == np.NaN
False

您可以使用 Python 条件和 nan 的 属性 从不等于自身来获得此行为:

>>> 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

您还可以这样做:

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    

我真的看不出有什么理由不取消警告。

最安全的方法是使用 warnings.catch_warnings 上下文管理器仅在您预期会发生的地方抑制警告 - 这样您就不会错过任何可能意外引发的额外 RuntimeWarnings在代码的其他部分:

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 的解决方案也可以工作,但最终您必须采取任何额外步骤以避免在所有 NaN 的数组上计算 np.nanmean 将产生一些额外的开销,您可以通过以下方式避免这些开销只是压制警告。此外,您的意图将更清楚地反映在代码中。

我在 3-D 数组上执行 np.nanmean 时收到此运行时警告,例如(时间、经度、纬度)。也许不是您问题的直接答案,但我想在我的案例中添加此警告消息可能与所有 NaN 值系列的点单元格值相关。