意思是,nanmean和警告:空切片的意思

Mic*_*rie 55 python warnings numpy

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

a = np.array([np.NaN, np.NaN])
b = np.array([np.NaN, np.NaN, 3])
Run Code Online (Sandbox Code Playgroud)

现在我发现两者的np.mean回报和:nanab

>>> np.mean(a)
nan
>>> np.mean(b)
nan
Run Code Online (Sandbox Code Playgroud)

自numpy 1.8(2016年4月20日发布)以来,我们一直很幸运nan,忽略了nan价值观:

>>> np.nanmean(b)
3.0
Run Code Online (Sandbox Code Playgroud)

然而,当阵列无关,但 nanmean价值,它提出了一个警告:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

我不喜欢压制警告; 是否有更好的功能,我可以用来获得np.mean没有警告的行为?

ali*_*i_m 53

我真的看不出有任何理由不去压制警告.

最安全的方法是使用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)
Run Code Online (Sandbox Code Playgroud)

@ dawg的解决方案也可以工作,但是为了避免np.nanmean在所有NaN阵列上进行计算,你必须采取的任何额外步骤都会产生一些额外的开销,你可以通过抑制警告来避免这些开销.此外,您的意图将更清晰地反映在代码中.

  • `warnings.filterwarnings(action='ignore', message='Mean ofempty slice')` 似乎更安全,因为它不会忽略您没有预料到的其他 `RuntimeWarning`。 (7认同)
  • 这是一个无用的警告,并没有像其他错误那样的"seterr" (3认同)
  • 您确定这里可能会提出的唯一警告是该警告吗?这就是通常不抑制警告的原因-如果这会引发另一个警告(可能在将来的版本中)怎么办? (2认同)
  • 当我搜索此警告时,我来到这里:RuntimeWarning:空切片的平均值。就我而言,这是由于找到空数组的平均值。我应该注意这个警告,因为这会导致 NaN 值,这给我在模型构建中带来了很大的痛苦,所以这个警告不应该被简单地忽略。 (2认同)

daw*_*awg 12

NaN值被定义为不等于本身:

>>> float('nan') == float('nan')
False
>>> np.NaN == np.NaN
False
Run Code Online (Sandbox Code Playgroud)

您可以使用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
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

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    
Run Code Online (Sandbox Code Playgroud)

  • 为什么使用 `try`/`except` 块?`np.nanmean(a)` 无论如何都会返回 `np.nan`。 (2认同)
  • dawg,当我运行 `np.nanmean(np.array([[np.NaN], [3]]),1)` 时,我收到运行时警告。我正在使用Python 3.4。我认为 ali_m 是对的,最好的办法就是抓住这个特定的警告。 (2认同)
  • @dawg 当你可以使用更清晰的“np.isnan(a).all()”时,为什么要使用“np.all(a != a)”的形式,它假设每个人都知道 nan != nan ? (2认同)