如何检查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那么,是什么您的建议告诉value是NaN或不是?
— 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.