平均值,nanmean和警告:空切片的平均值


74

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

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

现在,我发现两者和的np.mean收益:nanab

>>> 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没有警告的行为?


1
为什么警告是一个问题?
Padraic Cunningham 2015年

23
我必须承认,警告没有任何意义。一种明智的行为是始终如一地返回nan; 另一种是持续提出例外。警告就是这样的反应。
Amadan 2015年

抑制警告有什么问题?您不必批量处理-仅在您知道可能np.nanmean在所有NaN阵列上使用的地方屏蔽警告。
ali_m 2015年

2
另外,您也不必看nanmean-与会得到相同的傻事np.mean([])
Amadan 2015年

3
您的问题实际上包含了我为该警告的含义所寻求的答案。
erickrf 2015年

Answers:


65

我真的看不出没有任何理由不仅仅抑制警告。

最安全的方法是使用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的解决方案也可以使用,但是最终为避免np.nanmean在所有NaN的数组上进行计算而必须采取的任何其他步骤将招致一些额外的开销,您可以通过抑制警告来避免这些开销。您的意图也将在代码中更加清楚地体现。


4
这是一个无用的警告,没有seterr其他错误可以解决
破天荒的2016年

2
您确定这里可能会提出的唯一警告是该特定警告吗?这就是通常不抑制警告的原因-如果这会引发另一个警告(可能在将来的版本中)怎么办?
Mr_and_Mrs_D

1
确实,@ Mr_and_Mrs_D似乎是掩盖代码中实际错误的好方法。Numpy可能会提出一个特定的警告,该警告将RuntimeWarning子类化。
naught101 '19

2
我搜索以下警告时来到了这里:RuntimeWarning:空片的平均值。在我的情况下,这是由于找到了一个空数组的平均值。我应该注意警告,因为这会导致NaN值,这使我对模型构建产生了很多痛苦,因此警告不应简单地被忽略。
mudassirkhan19

2
warnings.filterwarnings(action='ignore', message='Mean of empty slice')似乎更安全,因为它不会忽略RuntimeWarning您未曾预料到的其他变量。
亚伦

17

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    

这适用于一维numpy数组。不幸的是,在我的实际用例中,我具有多维数据,并且沿一维取平均值。例如np.nanmean(np.array([[np.NaN], [3]]),1)
Michael Currie

然后添加适当的切片。此外,np.nanmean(np.array([[np.NaN], [3]]),1)似乎按预期工作...
dawg 2015年

2
为什么要使用try/except块?无论如何np.nanmean(a)都会返回np.nan
ali_m 2015年

令我try / except惊讶的是,它像其他Python代码所使用的可能期望与常规返回值不同的语法将其放入一个块中一样。
dawg 2015年

此外,沿着仅包含NaN的多维数组的一个轴返回标量np.nan将是错误的np.nanmean
ali_m 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.