【问题标题】:How can I check for NaN values?如何检查 NaN 值?
【发布时间】:2010-10-30 23:46:18
【问题描述】:

float('nan') 结果为 Nan(不是数字)。但是我该如何检查呢?应该很容易,但我找不到。

【问题讨论】:

标签: python math


【解决方案1】:

测试 NaN 的常用方法是查看它是否等于自身:

def isNaN(num):
    return num != num

【讨论】:

  • 警告词:在下面引用 Bear 的评论“对于坚持使用 python
  • 我敢肯定,考虑到运算符重载,我可以通过多种方式混淆这个函数。使用 math.isnan()
  • 它在上面提到的 754 规范中说 NaN==NaN 应该始终为 false,尽管它并不总是这样实现。无论如何,这不可能是数学和/或numpy在幕后检查它的方式吗?
  • 尽管这行得通,并且在某种程度上是有道理的,但我是一个有原则的人,我在此宣布这是被禁止的巫术。请改用 math.isnan。
  • @djsadinoff 混淆还有其他缺点吗? math.isnan() 不能检查字符串值,所以这个解决方案看起来更健壮。
【解决方案2】:

math.isnan(x)

如果 x 是 NaN(不是数字),则返回 True,否则返回 False

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True

【讨论】:

  • @charlie-parker :在 Python3 中,math.isnan 仍然是数学模块的一部分。 docs.python.org/3/library/math.html#math.isnan 。如果你愿意,可以使用 numpy.isnan,这个答案只是一个建议。
  • math.isnan 优先于np.isnan() 吗?
  • @TMWP 可能...import numpy 占用大约 15 MB 的 RAM,而 import math 占用大约 0.2 MB
  • @TMWP:如果您使用 NumPy,numpy.isnan 是一个更好的选择,因为它可以处理 NumPy 数组。如果您不使用 NumPy,那么获取 NumPy 依赖项并花时间加载 NumPy 只是为了进行 NaN 检查没有任何好处(但如果您正在编写执行 NaN 检查的代码,那么您可能 应该使用 NumPy)。
  • @jungwook 这实际上是行不通的。你的表达总是是假的。也就是说,float('nan') == float('nan') 返回False——这是一个奇怪的约定,但基本上是 NaN 定义的一部分。您想要的方法实际上是下面 Chris Jester-Young 发布的方法。
【解决方案3】:

math.isnan()

或将数字与自身进行比较。 NaN 总是 != NaN,否则(例如,如果它一个数字)比较应该成功。

【讨论】:

  • 适用于使用 python
【解决方案4】:

numpy.isnan(number) 告诉你它是否是NaN

【讨论】:

  • 也适用于 python 2.7 版。
  • numpy.all(numpy.isnan(data_list)) 如果您需要确定列表中的所有元素是否都是 nan 也很有用
  • 不需要 NumPy:all(map(math.isnan, [float("nan")]*5))
  • 当这个答案写于 6 年前时,Python 2.5 仍在普遍使用 - 而 math.isnan 不是标准库的一部分。现在,我真的希望在很多地方都不是这样!
  • 请注意 np.isnan() 不处理 decimal.Decimal 类型(与许多 numpy 的函数一样)。 math.isnan() 确实处理。
【解决方案5】:

如果你卡在

def isNaN(x):
    return str(x) == str(1e400*0)

【讨论】:

    【解决方案6】:

    使用 python

    def isNaN(x):
        return str(float(x)).lower() == 'nan'
    

    这适用于我在 Solaris 5.9 机器上使用 python 2.5.1 和在 Ubuntu 10 上使用 python 2.6.5

    【讨论】:

    • 这不太便携,因为 Windows 有时称它为 -1.#IND
    【解决方案7】:

    好吧,我进入了这篇文章,因为我在功能上遇到了一些问题:

    math.isnan()
    

    运行这段代码时出现问题:

    a = "hello"
    math.isnan(a)
    

    它引发异常。 我的解决方案是再次检查:

    def is_nan(x):
        return isinstance(x, float) and math.isnan(x)
    

    【讨论】:

    • 它可能被否决了,因为 isnan() 采用浮点数,而不是字符串。该功能没有任何问题,问题仅在于他尝试使用它。 (对于那个特定的用例,他的解决方案是有效的,但这不是这个问题的答案。)
    • 以这种方式检查类型时要小心。这将不起作用,例如对于 numpy.float32 NaN。最好使用 try/except 构造:def is_nan(x): try: return math.isnan(x) except: return False
    • NaN not 表示值不是有效数字。指定特定结果未定义是 IEEE 浮点表示的一部分。例如0 / 0。因此询问“hello”是否为nan是没有意义的。
    • 这样更好,因为 NaN 可以出现在任何字符串、整数或浮点数列表中,所以检查很有用
    • 我必须完全实现这个来处理 pandas 中的字符串列。
    【解决方案8】:

    我实际上只是遇到了这个问题,但对我来说它正在检查 nan、-inf 或 inf。我刚用过

    if float('-inf') < float(num) < float('inf'):
    

    这对于数字是正确的,对于 nan 和 inf 都是错误的,并且会引发字符串或其他类型的异常(这可能是一件好事)。此外,这不需要导入任何库,如 math 或 numpy(numpy 太大了,任何已编译应用程序的大小都会翻倍)。

    【讨论】:

    • math.isfinite 直到 Python 3.2 才被引入,所以鉴于 @DaveTheScientist 的答案于 2012 年发布,它并不完全是“重新发明 [ing] the wheel” - 解决方案仍然适用于那些使用 Python 的人2.
    • 这对于需要在 pd.eval 表达式中检查 NaN 的人很有用。例如pd.eval(float('-inf') &lt; float('nan') &lt; float('inf')) 将返回False
    【解决方案9】:

    我正在从以字符串'Nan' 发送NaN 的网络服务接收数据。但是我的数据中也可能有其他类型的字符串,所以一个简单的float(value) 可能会引发异常。我使用了以下已接受答案的变体:

    def isnan(value):
      try:
          import math
          return math.isnan(float(value))
      except:
          return False
    

    要求:

    isnan('hello') == False
    isnan('NaN') == True
    isnan(100) == False
    isnan(float('nan')) = True
    

    【讨论】:

    • try: int(value)
    • @chwi 那么你的建议对value 是否为NaN 有何影响?
    • 好吧,作为“不是数字”,我猜任何不能转换为 int 的东西实际上都不是数字,try 语句会失败吗?试试,返回true,除了返回false。
    • @chwi 好吧,从字面上理解“不是数字”,你是对的,但这不是重点。事实上,我正在寻找 NaN 的语义是什么(就像在 python 中你可以从 float('inf') * 0 得到什么),因此虽然字符串 'Hello' 不是数字,但它也不是 @987654331 @ 因为NaN 仍然是一个数值!
    • @chwi:你是对的,如果异常处理是针对特定异常的。但是在这个答案中,已经处理了通用异常。所以不需要检查int(value) 对于所有异常,False 将被写入。
    【解决方案10】:

    判断变量是NaN还是None的所有方法:

    无类型

    In [1]: from numpy import math
    
    In [2]: a = None
    In [3]: not a
    Out[3]: True
    
    In [4]: len(a or ()) == 0
    Out[4]: True
    
    In [5]: a == None
    Out[5]: True
    
    In [6]: a is None
    Out[6]: True
    
    In [7]: a != a
    Out[7]: False
    
    In [9]: math.isnan(a)
    Traceback (most recent call last):
      File "<ipython-input-9-6d4d8c26d370>", line 1, in <module>
        math.isnan(a)
    TypeError: a float is required
    
    In [10]: len(a) == 0
    Traceback (most recent call last):
      File "<ipython-input-10-65b72372873e>", line 1, in <module>
        len(a) == 0
    TypeError: object of type 'NoneType' has no len()
    

    NaN 类型

    In [11]: b = float('nan')
    In [12]: b
    Out[12]: nan
    
    In [13]: not b
    Out[13]: False
    
    In [14]: b != b
    Out[14]: True
    
    In [15]: math.isnan(b)
    Out[15]: True
    

    【讨论】:

      【解决方案11】:

      这里有一个答案:

      • 遵循 IEEE 754 标准的 NaN 实现
        • 即:python的NaN:float('nan')numpy.nan...
      • 任何其他对象:字符串或其他对象(遇到时不会引发异常)

      按照标准实现的 NaN 是唯一一个与自身进行不等比较应返回 True 的值:

      def is_nan(x):
          return (x != x)
      

      还有一些例子:

      import numpy as np
      values = [float('nan'), np.nan, 55, "string", lambda x : x]
      for value in values:
          print(f"{repr(value):<8} : {is_nan(value)}")
      

      输出:

      nan      : True
      nan      : True
      55       : False
      'string' : False
      <function <lambda> at 0x000000000927BF28> : False
      

      【讨论】:

      • 我正在检查的系列是缺少值的字符串是 'nans' (???) 所以这个解决方案适用于其他人失败的地方。
      • numpy.nan 是一个普通的 Python float 对象,就像 float('nan') 返回的那种。您在 NumPy 中遇到的大多数 NaN 都不是 numpy.nan 对象。
      • numpy.nan 定义了它的 NaN 值 on its own in the underlying library in C。它不包装 python 的 NaN。但现在,它们都符合 IEEE 754 标准,因为它们依赖于 C99 API。
      • @user2357112supportsMonica:Python 和 numpy NaN 实际上的行为方式不同:float('nan') is float('nan')(非唯一)和 np.nan is np.nan(唯一)
      • @x0s:这与 NumPy 无关。 np.nan 是一个特定对象,而每个 float('nan') 调用都会产生一个新对象。如果你做了nan = float('nan'),那么你也会得到nan is nan。如果你用np.float64('nan') 之类的东西构造了一个实际 NumPy NaN,那么you'd get np.float64('nan') is not np.float64('nan') too
      【解决方案12】:

      对于浮点类型的nan

      >>> import pandas as pd
      >>> value = float(nan)
      >>> type(value)
      >>> <class 'float'>
      >>> pd.isnull(value)
      True
      >>>
      >>> value = 'nan'
      >>> type(value)
      >>> <class 'str'>
      >>> pd.isnull(value)
      False
      

      【讨论】:

        【解决方案13】:

        对于 panda 中的字符串取 pd.isnull:

        if not pd.isnull(atext):
          for word in nltk.word_tokenize(atext):
        

        NLTK 的特征提取函数

        def act_features(atext):
        features = {}
        if not pd.isnull(atext):
          for word in nltk.word_tokenize(atext):
            if word not in default_stopwords:
              features['cont({})'.format(word.lower())]=True
        return features
        

        【讨论】:

        • 这个减少是什么?
        • isnull 不仅对 NaN 值返回 true。
        【解决方案14】:

        如何从混合数据类型列表中删除 NaN(浮点)项

        如果您在可迭代中混合了类型,这里有一个不使用 numpy 的解决方案:

        from math import isnan
        
        Z = ['a','b', float('NaN'), 'd', float('1.1024')]
        
        [x for x in Z if not (
                              type(x) == float # let's drop all float values…
                              and isnan(x) # … but only if they are nan
                              )]
        
        ['a', 'b', 'd', 1.1024]

        短路求值意味着isnan 不会被非'float' 类型的值调用,因为False and (…) 可以快速求值为False,而无需求值右侧。

        【讨论】:

          【解决方案15】:

          您可以通过以下三种方式测试变量是否为“NaN”。

          import pandas as pd
          import numpy as np
          import math
          
          # For single variable all three libraries return single boolean
          x1 = float("nan")
          
          print(f"It's pd.isna: {pd.isna(x1)}")
          print(f"It's np.isnan: {np.isnan(x1)}}")
          print(f"It's math.isnan: {math.isnan(x1)}}")
          

          输出

          It's pd.isna: True
          It's np.isnan: True
          It's math.isnan: True
          

          【讨论】:

          • pd.isna(value) 省去了很多麻烦!像魅力一样工作!
          • pd.isnan()pd.isna()?这就是问题:D
          • 这个答案的第 3 版是正确的并且格式正确。这个(现在是 7 个)又错了。回滚为“不想要你的编辑”,而编辑改进了答案,wtf。
          • 附注我发现if not np.isnan(x): 非常有用。
          【解决方案16】:

          在 Python 3.6 中,检查字符串值 x math.isnan(x) 和 np.isnan(x) 会引发错误。 因此,如果我事先不知道它是一个数字,我无法检查给定的值是否为 NaN。 以下似乎解决了这个问题

          if str(x)=='nan' and type(x)!='str':
              print ('NaN')
          else:
              print ('non NaN')
          

          【讨论】:

            【解决方案17】:

            似乎在检查它是否等于自己

            x!=x
            

            是最快的。

            import pandas as pd 
            import numpy as np 
            import math 
            
            x = float('nan')
            
            %timeit x!=x                                                                                                                                                                                                                        
            44.8 ns ± 0.152 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
            
            %timeit math.isnan(x)                                                                                                                                                                                                               
            94.2 ns ± 0.955 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
            
            %timeit pd.isna(x) 
            281 ns ± 5.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
            
            %timeit np.isnan(x)                                                                                                                                                                                                                 
            1.38 µs ± 15.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
            
            

            【讨论】:

            • 值得注意的是,即使存在无穷大问题,这也有效。也就是说,如果 z = float('inf')z != z 的计算结果为 false。
            • 在我的电脑上z=float('inf') 然后z==z 给出True。 x=float('nan') 然后 x==x 给 False。
            【解决方案18】:

            比较pd.isnamath.isnannp.isnan 以及它们处理不同类型对象的灵活性。

            下表显示了是否可以使用给定方法检查对象的类型:

            
            +------------+-----+---------+------+--------+------+
            |   Method   | NaN | numeric | None | string | list |
            +------------+-----+---------+------+--------+------+
            | pd.isna    | yes | yes     | yes  | yes    | yes  |
            | math.isnan | yes | yes     | no   | no     | no   |
            | np.isnan   | yes | yes     | no   | no     | yes  | <-- # will error on mixed type list
            +------------+-----+---------+------+--------+------+
            
            

            pd.isna

            检查不同类型缺失值的最灵活方法。


            没有一个答案涵盖pd.isna 的灵活性。虽然math.isnannp.isnan 将为NaN 值返回True,但您无法检查不同类型的对象,例如None 或字符串。这两种方法都会返回错误,因此检查具有混合类型的列表会很麻烦。这虽然 pd.isna 很灵活,并且会为不同类型的类型返回正确的布尔值:

            In [1]: import pandas as pd
            
            In [2]: import numpy as np
            
            In [3]: missing_values = [3, None, np.NaN, pd.NA, pd.NaT, '10']
            
            In [4]: pd.isna(missing_values)
            Out[4]: array([False,  True,  True,  True,  True, False])
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-03-26
              • 2012-02-05
              • 2018-09-28
              相关资源
              最近更新 更多