如何检查 NaN 值?

float('nan')表示 NaN (不是一个数字)。但是如何检查它呢?

2413417 次浏览

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

def isNaN(num):return num != num

使用#0

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

math.isnan()

或者比较数字本身。NaN总是!=NaN,否则(例如,如果它是一个数字)比较应该成功。

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

另一种方法,如果你卡在<2.6上,你没有numpy,也没有IEEE 754支持:

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

使用python<2.6我最终得到了

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

这适用于我在Solaris 5.9 box上的python 2.5.1和在Ubuntu 10上的python 2.6.5

好吧,我进入这篇文章,因为我有一些问题的功能:

math.isnan()

运行此代码时出现问题:

a = "hello"math.isnan(a)

它会引发异常。我的解决方案是做另一个检查:

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

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

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

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

我从一个Web服务接收数据,该服务将NaN作为字符串'Nan'发送。但我的数据中也可能有其他类型的字符串,因此简单的float(value)可能会引发异常。我使用了以下接受答案的变体:

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

业务需求

isnan('hello') == Falseisnan('NaN') == Trueisnan(100) == Falseisnan(float('nan')) = True

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

无类型

In [1]: from numpy import math
In [2]: a = NoneIn [3]: not aOut[3]: True
In [4]: len(a or ()) == 0Out[4]: True
In [5]: a == NoneOut[5]: True
In [6]: a is NoneOut[6]: True
In [7]: a != aOut[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) == 0Traceback (most recent call last):File "<ipython-input-10-65b72372873e>", line 1, in <module>len(a) == 0TypeError: object of type 'NoneType' has no len()

NaN型

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

以下是与之合作的答案:

  • 符合IEEE 754标准的NaN实现
    • IE: python的NaN:float('nan')numpy.nan
  • 任何其他对象:字符串或其他什么(如果遇到,不会引发异常)

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

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

举几个例子:

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

输出:

nan      : Truenan      : True55       : False'string' : False<function <lambda> at 0x000000000927BF28> : False

对于浮点型的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

对于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())]=Truereturn features

如何从混合数据类型列表中删除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]

Short-circuit evaluation means that isnan will not be called on values that are not of type 'float', as False and (…) quickly evaluates to False without having to evaluate the right-hand side.

这里有三种方法可以测试变量是否为“NaN”。

import pandas as pdimport numpy as npimport math
# For single variable all three libraries return single booleanx1 = 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: TrueIt's np.isnan: TrueIt's math.isnan: True

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

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

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

x!=x

是最快的。

import pandas as pdimport numpy as npimport math
x = float('nan')
%timeit x!=x44.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)

比较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])