如何检查 NaN 值

How to check for NaN values

提问人:Jack Ha 提问时间:6/3/2009 最后编辑:cottontailJack Ha 更新时间:11/2/2023 访问量:2723483

问:

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

Python 数学 nan

评论

31赞 Craig McQueen 1/22/2010
有关 Python 中 NaN 的一些历史,请参阅 PEP 754。python.org/dev/peps/pep-0754
4赞 Michał Šrajer 2/5/2023
只是为了好玩,NaN 是一个数字:;-Pisinstance(float("nan"), Number)

答:

598赞 C. K. Young 6/3/2009 #1

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

def isNaN(num):
    return num != num

评论

10赞 mavnn 1/26/2010
警告词:引用 Bear 在下面的评论“对于坚持使用 python <= 2.5 的人。Nan != Nan 工作不可靠。改用numpy。话虽如此,我实际上从未见过它失败。
49赞 djsadinoff 8/12/2011
我敢肯定,考虑到运算符重载,我有很多方法可以混淆这个函数。使用 math.isnan()
9赞 Hari Ganesan 4/2/2014
在上面提到的 754 规范中,它说 NaN==NaN 应该始终为 false,尽管它并不总是这样实现。这是不可能的,这就是数学和/或numpy在引擎盖下检查它的方式吗?
61赞 Gonzalo 10/17/2019
尽管这有效,而且在某种程度上是有道理的,但我是一个有原则的人,我特此宣布这是被禁止的巫术。请改用 math.isnan。
10赞 Tobias Geisler 6/28/2020
如果您的输入包含字符串,则这是正确答案。(@williamtorkington) 并且在这种情况下都会中断。np.isnanmath.isnan
2066赞 gimel 6/3/2009 #2

使用 math.isnan

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

评论

12赞 gimel 9/8/2016
@charlie-parker :在 Python3 中,math.isnan 仍然是 math 模块的一部分。docs.python.org/3/library/math.html#math.isnan .如果您愿意,请使用 numpy.isnan,此答案只是一个建议。
84赞 TMWP 8/1/2017
是首选?math.isnannp.isnan()
90赞 petrpulc 9/12/2017
@TMWP可能...... 大约需要 15 MB 的 RAM,而需要大约 0,2 MBimport numpyimport math
40赞 user2357112 2/21/2019
@TMWP:如果您使用的是 NumPy,则是一个更好的选择,因为它可以处理 NumPy 数组。如果你不使用 NumPy,那么获取 NumPy 依赖项并花时间加载 NumPy 只是为了 NaN 检查是没有好处的(但如果你正在编写执行 NaN 检查的代码,那么你可能应该使用 NumPy)。numpy.isnan
11赞 Mike 7/11/2019
@jungwook 这实际上行不通。你的表达总是假的。也就是说,返回——这是一个奇怪的约定,但基本上是 NaN 定义的一部分。你想要的方法实际上是下面Chris Jester-Young发布的方法。float('nan') == float('nan')False
28赞 Tomalak 6/3/2009 #3

math.isnan()

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

评论

6赞 Bear 1/18/2010
对于坚持使用 python 的人来说,<= 2.5。Nan != Nan 工作不可靠。改用numpy。
281赞 mavnn 6/3/2009 #4

numpy.isnan(number)告诉你是不是。NaN

评论

3赞 Michel Keijzers 12/5/2012
也适用于 python 2.7 版。
14赞 Jay Prall 2/28/2014
numpy.all(numpy.isnan(data_list))如果您需要确定列表中的所有元素是否都是 nan,也很有用
6赞 sleblanc 3/28/2015
不需要 NumPy:all(map(math.isnan, [float("nan")]*5))
8赞 mavnn 3/30/2015
当这个答案在 6 年前写成时,Python 2.5 仍在普遍使用 - math.isnan 不是标准库的一部分。现在,我真的希望很多地方不是这样!
5赞 comte 5/16/2018
请注意,np.isnan() 不处理十进制。十进制类型(与许多numpy的函数一样)。math.isnan() 处理。
17赞 Josh Lee 1/26/2010 #5

如果您卡在 <2.6 上,您没有 numpy,并且没有 IEEE 754 支持,则使用另一种方法:

def isNaN(x):
    return str(x) == str(1e400*0)
10赞 Mauro Bianchi 6/17/2010 #6

使用 python < 2.6,我最终得到了

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

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

评论

6赞 Mike T 2/1/2012
这不太便携,因为 Windows 有时称之为-1.#IND
27赞 Idok 7/5/2012 #7

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

math.isnan()

运行此代码时出现问题:

a = "hello"
math.isnan(a)

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

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

评论

5赞 Peter Hansen 7/7/2013
它可能被否决了,因为 isnan() 接受浮点数,而不是字符串。这个功能没有错,问题只在于他尝试使用它。(对于那个特定的用例,他的解决方案是有效的,但它不是这个问题的答案。
7赞 Rob 3/24/2014
以这种方式检查类型时要小心。例如,对于numpy.float32 NaN,这将不起作用。最好使用 try/except 结构:def is_nan(x): try: return math.isnan(x) except: return False
4赞 Brice M. Dempsey 7/17/2015
NaN 并不意味着值不是有效数字。它是IEEE浮点表示的一部分,用于指定特定结果未定义。例如 0 / 0。因此,问“你好”是否是楠是没有意义的。
2赞 RAFIQ 3/11/2016
这更好,因为 NaN 可以进入任何字符串、整数或浮点数列表,因此检查很有用
0赞 Cristian Garcia 6/5/2020
我必须实现这一点来处理 pandas 中的字符串列。
33赞 DaveTheScientist 9/26/2012 #8

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

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

对于数字来说,这是真的,对于 nan 和 inf 来说都是 false,并且会为字符串或其他类型等内容引发异常(这可能是一件好事)。此外,这不需要导入任何库,如 math 或 numpy(numpy 太大了,它的大小是任何编译应用程序的两倍)。

评论

12赞 sudo_coffee 11/23/2016
math.isfinite直到 Python 3.2 才被引入,所以鉴于 2012 年发布的@DaveTheScientist的答案,它并不完全是“重新发明轮子”——解决方案仍然代表那些使用 Python 2 的人。
0赞 Derek O 5/25/2021
这对于需要检查表达式中 NaN 的用户很有用。例如将返回pd.evalpd.eval(float('-inf') < float('nan') < float('inf'))False
7赞 Mahdi 6/23/2016 #9

我正在从以字符串形式发送的 Web 服务接收数据。但是我的数据中也可能有其他类型的字符串,所以一个简单的字符串可能会引发异常。我使用了接受答案的以下变体: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

评论

1赞 chwi 7/6/2016
try: int(value)
0赞 Mahdi 7/6/2016
@chwi那么,你的建议说明了存在与否吗?valueNaN
0赞 chwi 7/7/2016
好吧,由于“不是一个数字”,任何不能转换为 int 的东西我猜实际上都不是数字,并且 try 语句会失败吗?尝试,返回 true,但返回 false。
0赞 Mahdi 7/7/2016
@chwi 好吧,从字面上理解“不是一个数字”,你是对的,但这不是重点。事实上,我正在寻找的正是语义是什么(就像在 python 中你可以得到什么一样),因此虽然字符串“Hello”不是一个数字,但它也不是,因为它仍然是一个数值!NaNfloat('inf') * 0NaNNaN
0赞 Harsha Biyani 1/15/2020
@chwi:如果异常处理是针对特定异常的,那么您是正确的。但在这个答案中,已经处理了通用异常。所以没有必要检查所有异常,都会写出来。int(value)False
4赞 siberiawolf61 12/7/2016 #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
49赞 x0s 5/24/2017 #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

评论

1赞 keithpjolley 11/4/2018
我正在检查的系列是缺少值的字符串是“nans”(???),因此此解决方案适用于其他解决方案失败的地方。
0赞 user2357112 4/14/2020
numpy.nan是一个常规的 Python 对象,就像 返回的 kind 一样。您在 NumPy 中遇到的大多数 NaN 都不会是对象。floatfloat('nan')numpy.nan
0赞 x0s 4/22/2020
numpy.nan在 C 的底层库中自行定义其 NaN 值。它不包装 python 的 NaN。但现在,它们都符合 IEEE 754 标准,因为它们依赖于 C99 API。
0赞 x0s 4/22/2020
@user2357112supportsMonica:Python 和 numpy NaN 实际上的行为方式并不相同:(非唯一)和(唯一)float('nan') is float('nan')np.nan is np.nan
1赞 user2357112 4/22/2020
@x0s:这与NumPy无关。 是一个特定的对象,而每次调用都会生成一个新对象。如果你这样做了,那么你也会得到。如果你用类似的东西构造了一个实际的 NumPy NaN,那么你会得到 np.float64('nan') 也不是 np.float64('nan')。np.nanfloat('nan')nan = float('nan')nan is nannp.float64('nan')
1赞 J11 7/17/2018 #12

对于 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赞 Max Kleiner 7/17/2018 #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

评论

0赞 Max Kleiner 8/7/2018
这种减少是什么?
0赞 4/20/2020
isnull 不仅为 NaN 值返回 true。
4赞 sleblanc 1/28/2019 #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]

短路评估意味着不会对非“浮点”类型的值调用,因为无需评估右侧即可快速评估。isnanFalse and (…)False

238赞 M. Hamza Rajput 3/3/2019 #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

评论

20赞 abhishake 10/16/2019
pd.isna(value) 省去了很多麻烦!像魅力一样工作!
4赞 mah65 4/13/2021
pd.isnan()或?这就是问题:Dpd.isna()
4赞 jemand771 5/20/2021
这个答案的第 3 版是正确的,格式很好。这个(现在是 7 个)又错了。回滚为“不想要您的编辑”,而编辑改进了答案 WTF。
2赞 Cam 10/22/2021
旁注:我发现非常有用。if not np.isnan(x):
4赞 wisbucky 10/1/2022
pd.isna('foo')也是唯一可以处理字符串的。 并将导致 TypeError 异常。np.isnan('foo')math.isnan('foo')
4赞 Valentin Goikhman 1/14/2020 #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')
59赞 Grzegorz 6/3/2020 #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)

评论

1赞 npengra317 10/31/2020
值得注意的是,即使存在无穷大问题,这也有效。也就是说,如果 的计算结果为 false。z = float('inf')z != z
1赞 matan h 12/10/2020
在我的电脑中,然后给出 True。 然后给出 False。z=float('inf')z==zx=float('nan')x==x
3赞 rvf 1/4/2022
在大多数(如果不是全部)情况下,这些速度差异只有在重复多次时才有意义。然后,无论如何,您将使用或其他张量库。numpy
1赞 wjandrea 4/3/2023
这是一个糟糕的比较。在此比例(纳秒)下,名称和属性查找时间非常重要。如果仅使用本地名称,则 和 之间的差异将消失;它们在我的系统上都是大约 35 ns。您可以在单元格模式下使用以下工具检查:1) <换行符> 2) <换行符>x != xmath.isnan(x)%timeit%%timeit x = float('nan')x != x%%timeit x = float('nan'); from math import isnanisnan(x)
0赞 MisterMiyagi 4/3/2023
注意:这些计时代表检查预先存在的变量,不能很好地泛化。当实际需要某个函数并且需要包装在 .当应用于需要迭代的数组时,诸如 之类的功能将具有非常不同的竞争性。math.isnanx != xlambdanumpynumpy.isnannumpyx != x
9赞 Erfan 6/29/2021 #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.isnamath.isnannp.isnanTrueNaNNonepd.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])

评论

0赞 turbonate 3/23/2023
这!!!!我来到这里试图弄清楚如何检查 NaN 和 None,根据用户输入的 excel 工作表,我可以得到它们。如果不是那些讨厌的用户,这将很容易!
0赞 cottontail 7/14/2023 #19

如果要检查非 NaN 的值,则否定用于标记 NaN 的任何值;pandas 有自己的专用函数来标记非 NaN 值。

lst = [1, 2, float('nan')]

m1 = [e == e for e in lst]              # [True, True, False]

m2 = [not math.isnan(e) for e in lst]   # [True, True, False]

m3 = ~np.isnan(lst)                     # array([ True,  True, False])

m4 = pd.notna(lst)                      # array([ True,  True, False])

如果要筛选非 NaN 的值,这将特别有用。对于 ndarray/Series 对象,是矢量化的,因此也可以使用它。==

s = pd.Series(lst)
arr = np.array(lst)

x = s[s.notna()]
y = s[s==s]                             # `==` is vectorized
z = arr[~np.isnan(arr)]                 # array([1., 2.])

assert (x == y).all() and (x == z).all()