如何检查NaN值?

Jac*_* Ha 862 python math

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

gim*_*mel 1112

math.isnan()

检查浮点数x是否为NaN(不是数字).NaN是IEEE 754标准的一部分.操作,例如但不限于inf*0,inf/inf或涉及NaN的任何操作,例如nan*1,返回NaN.

2.6版中的新功能.

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True
Run Code Online (Sandbox Code Playgroud)

  • 是`math.isnan`首选`np.isnan()`? (29认同)
  • @TMWP可能......`import numpy`需要大约15 MB的RAM,而`import math`需要大约0.2 MB (23认同)
  • @ charlie-parker:在Python3中,math.isnan仍然是数学模块的一部分.https://docs.python.org/3/library/math.html#math.isnan.如果你愿意,可以使用numpy.isnan,这个答案只是一个建议. (5认同)
  • @TMWP:如果您使用的是NumPy,则numpy.isnan是更好的选择,因为它可以处理NumPy数组。如果您不使用NumPy,那么获取NumPy依赖关系并花费时间仅为进行NaN检查而加载NumPy是没有好处的(但是,如果您编写的是执行NaN检查的代码,则可能*应该*正在使用NumPy)。 (5认同)
  • @jungwook 这实际上不起作用。你的表达*总是*错误的。也就是说,“float('nan') == float('nan')”返回“False”——这是一个奇怪的约定,但基本上是 NaN 定义的一部分。您想要的方法实际上是下面由 Chris Jester-Young 发布的方法。 (4认同)
  • @kotrfa:只有当你在单个标量上调用它时,并且如果你在 NumPy 中经常这样做,那么你就错误地使用了 NumPy。有效使用 NumPy 就是进行整个数组操作。[在大型数组上调用 `numpy.isnan` 比使用 `math.isnan` 快 200 倍以上。](https://ideone.com/wp2AGO) (4认同)
  • 我在上面的代码中遇到了错误。是因为python 3吗?然而, numpy.isnan(float('nan')) 确实有效。为什么我要使用 math 而不是 numpy? (2认同)
  • @ SeatingBull请参见https://docs.python.org/3/library/functions.html#float“如果参数是字符串,则应包含十进制数字”,或“ Infinity”“ inf”“ nan” (2认同)
  • 注意:仅适用于浮动;当 x 是 str 时抛出 TypeError。 (2认同)
  • `math.isnan` 似乎比 `np.isnan` 快(在我的机器上大约是 20 倍) (2认同)

Chr*_*ung 316

测试NaN的常用方法是查看它是否与自身相同:

def isNaN(num):
    return num != num
Run Code Online (Sandbox Code Playgroud)

  • 我确信,鉴于运算符重载,有很多方法可以混淆这个函数.和math.isnan()一起去 (19认同)
  • 尽管这可行,并且在某种程度上是有道理的,但我是一个有原则的人,我特此宣布这是被禁止的巫术。请改用 math.isnan。 (19认同)
  • 警告的话:引用熊的评论如下"对于那些被蟒蛇<= 2.5的人.南!=南没有可靠的工作.用numpy代替." 话虽如此,我实际上并没有看到它失败. (8认同)
  • 这个答案很糟糕;它依赖于“nan”是宇宙中唯一不等于其自身的事物。至少应该是“return isinstance(num, float) and num != num”。验证类型的开销比实际出错的可能性要好,这可能是错误的。 (8认同)
  • 它在上面提到的754规范中说NaN == NaN应该总是假的,尽管它并不总是如此实现.是不是有可能这是数学和/或numpy如何在引擎盖下检查这个? (4认同)
  • @djsadinoff 混乱还有其他缺点吗?math.isnan() 无法检查字符串值,因此该解决方案似乎更可靠。 (4认同)
  • `math.isnan(x)` 要求 x 是一个实数,这会导致在检查 NaN 之前验证 x 的类型(并可能将 x 转换为实数)的开销。`x != x` 简洁而健壮——太棒了! (3认同)
  • 如果您的**输入包含字符串**,这就是正确的答案。(@williamtorkington) 在这种情况下,`np.isnan` 和 `math.isnan` 都会被破坏。 (3认同)
  • 谢谢 。如果对标量进行操作,这也比使用 np.isnan 快 15-20 倍 (2认同)
  • @2Toad 这更简洁,但不太健壮。类型检查对于准确来说是必要的,如果有人如此关心检查类型的最小开销(不需要转换),那么他们就不应该使用 Python。 (2认同)

mav*_*vnn 132

numpy.isnan(number)NaN在Python 2.5中告诉你它是否存在.

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

Grz*_*orz 31

似乎检查它是否等于自身

x!=x
Run Code Online (Sandbox Code Playgroud)

是最快的。

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)

Run Code Online (Sandbox Code Playgroud)

  • 在大多数(如果不是全部)情况下,这些速度差异只有在重复多次后才会相关。无论如何,你将使用“numpy”或其他张量库。 (3认同)

Dav*_*ist 28

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

if float('-inf') < float(num) < float('inf'):
Run Code Online (Sandbox Code Playgroud)

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

  • `math.isfinite`直到Python 3.2才被引入,所以鉴于@DaveTheScientist的回答是在2012年发布的,它并不完全是"重新发明轮子" - 解决方案仍然代表那些使用Python 2的人. (8认同)

x0s*_*x0s 28

这是一个回答:

  • python 非唯一 NaN:float('nan')
  • numpy unique NaN(singleton):np.nan
  • 任何其他对象:字符串或其他(遇到异常时不引发异常)

这里是:

import numpy as np

def is_nan(x):
    return (x is np.nan or x != x)
Run Code Online (Sandbox Code Playgroud)

还有一些例子:

values = [float('nan'), np.nan, 55, "string", lambda x : x]
for value in values:
    print "{:<8} : {}".format(repr(value), is_nan(value))
Run Code Online (Sandbox Code Playgroud)

输出:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False
Run Code Online (Sandbox Code Playgroud)


M. *_*put 24

您可以通过以下三种方法测试变量是否为“ 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)}")
Run Code Online (Sandbox Code Playgroud)

输出量

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)}")
Run Code Online (Sandbox Code Playgroud)

  • pd.isna(value) 省去了很多麻烦!像魅力一样工作! (9认同)
  • 这个答案的第三版是正确的并且格式良好。这个(现在是7)又错了。回滚为“不需要您的编辑”,而编辑改进了答案,wtf。 (4认同)
  • `pd.isna('foo')` 也是唯一可以处理字符串的。`np.isnan('foo')` 和 `math.isnan('foo')` 将导致 TypeError 异常。 (4认同)
  • `pd.isnan()` 还是 `pd.isna()`?这就是问题所在:D (2认同)
  • 旁注我发现 ```if not np.isnan(x):``` 非常有用。 (2认同)

Tom*_*lak 22

math.isnan()

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

  • 对于卡住python <= 2.5的人.Nan!= Nan没有可靠的工作.用numpy代替. (6认同)

Jos*_*Lee 17

另一种方法,如果你坚持<2.6,你没有numpy,并且你没有IEEE 754支持:

def isNaN(x):
    return str(x) == str(1e400*0)
Run Code Online (Sandbox Code Playgroud)


Ido*_*dok 9

好吧,我输入了这篇文章,因为我的功能存在一些问题:

math.isnan()
Run Code Online (Sandbox Code Playgroud)

运行此代码时出现问题:

a = "hello"
math.isnan(a)
Run Code Online (Sandbox Code Playgroud)

它引发了例外.我的解决方案是再次检查:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)
Run Code Online (Sandbox Code Playgroud)

  • 小心以这种方式检查类型.这不适用于例如numpy.float32 NaN.最好使用try/except构造:`def is_nan(x):try:return math.isnan(x)except:return False` (6认同)
  • NaN不*表示值不是有效数字.它是IEEE浮点表示的一部分,用于指定特定结果未定义.例如0/0.因此询问"hello"是否为nan是没有意义的. (3认同)
  • 它可能被否决了,因为isnan()需要浮点数而不是字符串。该函数没有任何问题,问题仅在于他尝试使用它。(对于该特定用例,他的解决方案是有效的,但这不是对该问题的答案。) (2认同)
  • 这更好,因为 NaN 可以出现在任何字符串、整数或浮点数列表中,所以检查很有用 (2认同)

Erf*_*fan 9

比较pd.isnamath.isnan以及np.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
+------------+-----+---------+------+--------+------+

Run Code Online (Sandbox Code Playgroud)

pd.isna

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


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


+------------+-----+---------+------+--------+------+
|   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
+------------+-----+---------+------+--------+------+

Run Code Online (Sandbox Code Playgroud)


Mau*_*chi 8

随着python <2.6,我最终得到了

def isNaN(x):
    return str(float(x)).lower() == 'nan'
Run Code Online (Sandbox Code Playgroud)

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

  • 这不太便于移植,因为Windows有时会将其称为-1.#IND` (4认同)

Mah*_*hdi 6

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

def isnan(value):
  try:
      import math
      return math.isnan(float(value))
  except:
      return False
Run Code Online (Sandbox Code Playgroud)

要求:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True
Run Code Online (Sandbox Code Playgroud)