【问题标题】:Unexpected nan behaviour when summing a numpy array full of nan对充满 nan 的 numpy 数组求和时出现意外的 nan 行为
【发布时间】:2018-07-02 12:02:07
【问题描述】:

这是一个有趣的话题,因为它可能导致代码中出现意外结果。假设我有一个如下数组;

import numpy as np

X = np.array([np.nan,np.nan,np.nan,np.nan,np.nan])

np.nanmean(X) 正确返回平均切片为空的警告并返回 nan。但是,当对数组 np.nansum(X) 求和时,它会返回 0.0。现在虽然在数学上是正确的(无和为 0),但预期返回的结果可能是 np.nan。

例如,我有一个函数,如果一个冰数据文件不存在,它将创建一个空的 nan 数组(180x360 点,每个点代表一个纬度/经度)。然后将该数组传递给一个函数,该函数对数组求和,以找出数组中的冰总量。如果期望值为 9-10 百万平方公里,而 nansum 返回 0,这可能会产生误导。如果冰的范围无论如何都在 0 左右,这尤其困难。 在下图中,这显然是一个丢失的数据文件,导致冰总和为 0.0,但并非所有情况都如此清晰。

我在开发网站上看到过这个讨论,并且想知道为什么np.nansum() 没有一个 kwarg 选项来返回 np.nan 如果需要,以及 B,是否有一个函数返回 True/False 如果整个矩阵都是nan?

【问题讨论】:

  • 来自documentation of np.nansum:“返回给定轴上的数组元素的总和,将非数字 (NaN) 视为零。”...我会说它返回 0.0 正是预期的行为。请注意,这在 numpy 1.8 中发生了变化(再次来自文档:“在 NumPy 版本中,对于全 NaN 或空的切片,返回
  • 0.0 是正确的,但在处理 nan 的某些情况下可能会导致问题。显然,如果 numpy 稍后发生更改,那么 nansum 的结果就不是那么直观了。
  • 旧 numpy 版本具有您期望的行为
  • 请参阅 here 了解导致更改的原始讨论。
  • 好的,我很感激,我对堆栈溢出比较陌生,感谢您的帮助。我不喜欢因为问一些我认为有趣的事情而得到的否定和敌意反应。它不会鼓励人们在此网站上发布问题

标签: python arrays numpy math nan


【解决方案1】:

改进 Brad Solomon 的解决方法。将 **kwargs 传递给 all() 允许部分 nan-tagging。

def nansumwrapper(a, **kwargs):
    mx = np.isnan(a).all(**kwargs)
    res = np.nansum(a, **kwargs)
    res[mx] = np.nan
    return res

【讨论】:

    【解决方案2】:

    Docs:

    在 NumPy 版本

    解决方法:

    def nansumwrapper(a, **kwargs):
        if np.isnan(a).all():
            return np.nan
        else:
            return np.nansum(a, **kwargs)
    
    a = np.array([np.nan, np.nan])
    b = np.array([np.nan, 1., 2.])
    
    
    nansumwrapper(a)
    # nan
    
    nansumwrapper(b)
    # 3.0
    

    您可以将 kwargs 传递给np.nansum():

    c = np.arange(12, dtype=np.float_).reshape(4,3)
    c[2:4, 1] = np.nan
    
    nansumwrapper(c, axis=1)
    # array([  3.,  12.,  14.,  20.])
    

    【讨论】:

      猜你喜欢
      • 2017-07-24
      • 2020-07-04
      • 2017-07-01
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 2020-01-19
      • 2017-08-12
      • 2020-09-14
      相关资源
      最近更新 更多