如何检查NaN值?


Answers:


1275

math.isnan(x)

返回True如果x为NaN(非数字),以及False其他。

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

5
@ charlie-parker:在Python3中,math.isnan仍然是math模块的一部分。docs.python.org/3/library/math.html#math.isnan。如果需要,请使用numpy.isnan,这只是一个建议。
吉梅尔'16

2
@ SeatingBull请参阅docs.python.org/3/library/functions.html#float “如果参数是字符串,则应包含十进制数字”或“ Infinity”,“ inf”,“ nan”
gimel 2016年

35
math.isnan首选np.isnan()
TMWP '17

34
@TMWP可能... import numpy占用大约15 MB的RAM,而import math占用大约0.2 MB
petrpulc

9
@TMWP:如果您使用的是NumPy,numpy.isnan则它是一个绝佳选择,因为它可以处理NumPy数组。如果您不使用NumPy,那么获取NumPy依赖项并花时间加载NumPy仅用于NaN检查是没有好处的(但是,如果您编写的是执行NaN检查的代码,则很可能应该使用NumPy)。
user2357112支持Monica19年

359

测试NaN的通常方法是查看其是否与自身相等:

def isNaN(num):
    return num != num

8
警告词:在下面引用Bear的评论:“对于受Python <= 2.5困扰的人。Nan!= Nan无法可靠地工作。请使用numpy。” 话虽如此,我实际上从未见过失败。
mavnn 2010年

22
我敢肯定,考虑到运算符的重载,有很多方法可以使此函数混淆。与math.isnan()一起使用
djsadinoff 2011年

4
它说在上述754规范中,NaN == NaN应该始终为假,尽管并非总是如此。反正这是不可能的,这是数学和/或numpy如何检查的吗?
Hari Ganesan 2014年

谢谢 。如果在标量上进行操作,这也比使用np.isnan快15-20倍
thomas.mac

5
即使这行得通,并且在一定程度上讲是有道理的,但我是一个有原则的人,在此宣布这是被禁止的巫术。请改用math.isnan。
贡萨洛

151

numpy.isnan(number)告诉您是否NaN存在。


3
也可以在python版本2.7中使用。
Michel Keijzers

6
numpy.all(numpy.isnan(data_list))如果您需要确定列表中的所有元素是否均为nan,它也很有用
Jay P.

3
无需NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc

6
6年前编写此答案时,Python 2.5仍然很普遍-而且math.isnan不在标准库中。现在,我真的很希望在很多地方不是这样!
mavnn

4
请注意,np.isnan()不能处理小数。小数类型(与许多numpy函数一样)。math.isnan()确实可以处理。
com18年

55

您可以通过以下三种方法测试变量是否为“ 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

2
pd.isna(value)节省了很多麻烦!像魅力一样工作!
Abhishake

1
ps.isna()解决了我的问题。谢谢!
darthbhyrava

32

这是使用的答案:

  • NaN实施符合IEEE 754标准
    • 即: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

1
我正在检查的序列是缺少值的字符串为'nans'(???),因此该解决方案在其他失败的情况下也可以使用。
keithpjolley

numpy.nan是常规的Python float对象,就像所返回的类型一样float('nan')。您在NumPy中遇到的大多数NaN都不是numpy.nan对象。
user2357112支持Monica

numpy.nan在C的基础库中自行定义其NaN值。它不包装python的NaN。但是现在,它们都依赖于C99 API,因此都符合IEEE 754标准。
x0s

@ user2357112supportsMonica:Python和numpy NaN实际上并不具有相同的行为:(float('nan') is float('nan')非唯一)和np.nan is np.nan(唯一)
x0s

@ x0s:与NumPy无关。np.nan是一个特定的对象,而每次float('nan')调用都会产生一个新对象。如果您这样做了nan = float('nan'),那么您也会得到的nan is nan。如果您使用构造一个实际的 NumPy NaN np.float64('nan'),则您将得到np.float64('nan') is not np.float64('nan')太多
user2357112支持Monica

28

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

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

这对于数字是正确的,对于nan和两个inf都是错误的,并且会为字符串或其他类型的东西引发异常(这可能是一件好事)。而且,这不需要导入任何库,例如math或numpy(numpy是如此之大,它会使任何已编译应用程序的大小增加一倍)。


9
math.isfinite直到Python 3.2才被引入,因此@DaveTheScientist的答案发布于2012年,它并不是完全“重新发明轮子”-解决方案仍然适用于使用Python 2的用户
。– sudo_coffee

22

math.isnan()

或将数字与其本身进行比较。NaN始终为!= NaN,否则(例如,如果数字)比较将成功。


6
对于使用python <= 2.5的人。Nan!= Nan不能可靠地工作。改用numpy。

16

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

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

11

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

math.isnan()

运行此代码时出现问题:

a = "hello"
math.isnan(a)

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

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

3
它可能被否决了,因为isnan()需要浮点数而不是字符串。该函数没有任何问题,问题仅在于他尝试使用它。(对于该特定用例,他的解决方案是有效的,但这不是对该问题的答案。)
Peter Hansen

6
以这种方式检查类型时要小心。这不适用于numpy.float32 NaN。最好使用try / except结构: def is_nan(x): try: return math.isnan(x) except: return False
Rob

3
为NaN并不能意味着一个值不是一个有效的数字。IEEE浮点表示法的一部分是指定未定义特定结果。例如0 /0。因此,询问“ hello”是否为nan毫无意义。
布里斯·登普西

2
这样会更好,因为NaN可以进入任何字符串,整数或浮点列表,因此非常有用的检查
RAFIQ

8

随着python <2.6我最终得到了

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

这适用于Solaris 5.9框上的python 2.5.1和Ubuntu 10上的python 2.6.5


6
Windows有时将其称为可移植性-1.#IND
Mike T

5

我正在从NaN以字符串形式发送的Web服务接收数据'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

1
try: int(value)
chwi

@chwi那么,是什么您的建议告诉valueNaN或不是?
Mahdi'7

好吧,作为“非数字”,我想不能转换为整数的任何东西实际上都不是数字,而try语句将失败?尝试返回true,但返回false。
chwi

@chwi好吧,从字面上理解“不是数字”,您是正确的,但这不是重点。实际上,我正在精确地寻找它的语义NaN(就像在python中可以从中得到的一样float('inf') * 0),因此尽管字符串“ Hello”不是数字,但它也不NaN是因为NaN它仍然是数字值!
Mahdi'7

@chwi:您是正确的,如果针对特定异常进行异常处理。但是在这个答案中,已经处理了通用异常。因此无需检查int(value)For All异常,False将被写入。
Harsha Biyani

3

判断变量是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

2

如何从混合数据类型列表中删除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不会调用非浮点类型的值,因为可以False and (…)快速评估而False无需评估右侧。


1

在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')

0

对于float类型的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

-5

对于熊猫字符串,请使用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

该减少什么呢?
Max Kleiner '18年

对于不只是NaN值,isnull返回true。
鲍里斯
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.