比较“ float('nan')”和“ math.nan”

时间:2019-04-17 13:30:29

标签: python equality

我有一个float变量,它可能是数字,也可能不是数字,我想检查是否是这种情况。通过x = float('nan'),我观察到一些令我惊讶的行为:

    print(x is math.nan)
>>> False

这意味着float('nan')math.nan是不同的对象,这没想到,但这没关系。但是,当我检查与==的相等性时,结果是相同的:

print(x == math.nan):
>>> False

如果我使用math.isnan(x),对于所有非数字都可以得到正确的结果。尽管如此,float('nan') == math.nan为什么不评估为True?。

6 个答案:

答案 0 :(得分:2)

在某种意义上,“不是数字”是指没有值。

传统上,按照IEEE浮点规范, 它并不等于自身

那是因为没有可比较的有意义的值。

实际上,some people use this fact to detect NaN是您的条件,因此您可以尝试使用x != x(尽管相关的问答可以提供更好的建议)。

表达式math.nan is math.nan是正确的,因为is进行对象身份比较,而不是值等效/相等比较。

答案 1 :(得分:1)

这不是特殊的行为:is返回两个对象是否实际上是在指同一事物(本质上是在内存中),而==返回两个对象是否具有相同的值。

要查看他们是否指的是同一事物,我们可以使用id()

>>> a = [1,2,3]
>>> b = a
>>> id(a)
140302781856200
>>> id(b)
140302781856200
>>> a == b
True
>>> a is b
True
>>> c = [1,2,3]
>>> id(c)
140302781864904
>>> a == c
True
>>> a is c
False

在这里,我们看到通过分配b = a,它们现在指向同一列表:因此,is==True。但是,当我们将c定义为具有与ab相同值的新变量时,它就是==,但是is返回{{1} }。

False也是如此。

答案 2 :(得分:1)

这是因为NaN只是一个浮点值。使用is不会检查变量是否具有相同的值,而是会检查它们是否是相同的对象。如果创建两个具有相同值的浮点数,则它们不是同一对象,它们是具有相同值的两个对象。以这个为例:

>>> a = float('nan')
>>> b = float('nan')
>>> a is b
False

因此,即使您以相同的方式创建两个NaN值,它们也不是同一对象。即使对于更简单的浮点数也是如此。试试这个:

>>> a = 1.
>>> b = 1.
>>> a is b
False

Python的默认版本重复使用 some 值,因此该值的任何实例都是同一对象。因此,以这个为例(请注意,缺少小数,这些是整数而不是浮点数):

>>> a = 1
>>> b = 1
>>> a is b
True

但这是您不应该依赖的实现细节,它可以随时更改,并且在python实现之间可能有所不同。但是即使这样,NaN也不是默认Python解释器为此目的提供的值之一。

您可以使用id函数手动检查两个变量是否为同一对象,该函数为同时存在的每个对象提供唯一的编号(尽管删除一个变量也可以重复使用这些编号,即使自动)。

>>> a=1.
>>> b=1.
>>> c=float('nan')
>>> d=float('nan')
>>> e=1
>>> f=1
>>> id(a)
139622774035752
>>> id(b)
139622774035872
>>> id(c)
139622774035824
>>> id(d)
139622774035800
>>> id(e)
139622781650528
>>> id(f)
139622781650528

关于它们为什么不相等的原因,这只是NaN在现代计算机中使用的定义的一部分。根据定义,NaN绝不能等于自己。它是有关浮点数如何工作的国际标准的一部分,并且这种行为已内置于现代CPU中。

答案 3 :(得分:0)

虽然它们不是同一对象(因为它们来自分别实现的不同模块)并且不相等(通过设计NaN != NaN),但是它们具有功能math.isnan(和{ {3}}(如果您想要向量化版本)正是为此目的:

import math
import numpy

math.isnan(math.nan)
# True
math.isnan(numpy.nan)
# True
math.isnan(float("nan"))
# True

尽管它们彼此不平等且不相同:

math.nan == numpy.nan or math.nan is numpy.nan
# False
math.nan == float("nan") or math.nan is float("nan")
# False
numpy.nan == float("nan") or numpy.nan is float("nan")
# False

答案 4 :(得分:0)

您可以使用内置于“float”中的“hex”函数

public static void Main() 
{ 
  var someObject = new MyClassWithEvents();
  someObject.SomeEventFired += () => 
  {
     // do whatever
  }; 
}

float('nan') == math.nan                   # FALSE

float('nan').hex() == math.nan.hex()       # TRUE

float('nan').hex() == float('nan').hex()   # TRUE

如果您在 Pandas 中使用查询,这将非常有用。我最近尝试使用:

float('nan').hex() == numpy.nan.hex()   # TRUE

应该检查 A 列是否为 NaN。但是,pandas 会自动将字符串“NaN”转换为浮点数。大多数人会推荐使用 df['A'].isna(),但在我们的例子中,尝试将表达式传递给方法,因此它应该处理任何表达式。 解决办法是:

df.eval('A == "NaN"')

答案 5 :(得分:0)

您可以将 nan 值转换为字符串进行比较。 像这样:

x=float("nan")
s_nan = str(x)
if s_nan == "nan":
   # What you need to do...
   print('x is not a number')
相关问题