【问题标题】:How to check for float('nan') in Python?如何在 Python 中检查 float('nan')?
【发布时间】:2022-01-13 06:29:52
【问题描述】:

在我正在处理的一些数据中,我遇到了float 类型的数据,这些数据用“nan”填充,即float('nan')

但是检查它并没有按预期工作:

float('nan') == float('nan')
>> False

你可以用math.isnan查看,但由于我的数据也包含字符串(例如:'nan',还有其他用户输入),所以不太方便:

import math
math.isnan(float('nan'))
>> True
math.isnan('nan')
>> TypeError: must be real number, not str

在理想情况下,我想检查一个值是否在所有可能的 NaN 值的列表中,例如:

import numpy as np
if x in ['nan', np.nan, ... ]:
    # Do something
    pass

现在的问题: 我怎样才能在使用这种方法的同时检查float('nan') 值?以及为什么等于float('nan') == float('nan')False

【问题讨论】:

  • if x == 'nan' or isnan(x)…?!
  • 更好的是,使用isnan 并清理您的数据,这样您就不必担心“或者它实际上是一个字符串?”
  • 如果 x 不是实数,if x == 'nan' or isnan(x) 将引发 TypeError。清理是一种解决方案,但如果可能的话,我宁愿一次性完成所有事情。另外我还是很好奇为什么float('nan) == float('nan')等于False
  • “但由于我的数据也包含字符串” - 听起来你应该先解决这个问题,然后使用isnan
  • “另外我还是很好奇为什么 float('nan) == float('nan') 等于 False” - 因为它的设计是这样的,x != x 将是一种方便的方法来测试 NaN没有 isnan 函数的设置(在 IEEE 754 的早期很常见),并且因为比较产生 True 实际上并没有更多用处。

标签: python


【解决方案1】:

你可以像这样检查 NaN 值,

 def isNaN(num):
    if num == 'nan':
        return True
    return num!= num 

【讨论】:

  • 'nan' != 'nan'False...
  • @Tomerikoo 已更正!
【解决方案2】:

这很行人,而且有点难看,但为什么不做以下呢?

import math
import numpy as np

if math.isnan(x) or x in ['nan', np.nan, ... ]:
    # Do something
    pass

我想推荐一个尤达表达式,但还没有完全解决。

如果您想扫除地毯下的所有内容,请将其放入 lambda 或函数中。

https://stackoverflow.com/a/64090763/1021819 开始,您可以尝试让迭代器以懒惰的方式评估任何内容。那么问题是,如果第一个条件的计算结果都不是True,那么math.isnan() 调用被执行并且仍然可以抛出TypeError。如果您懒惰地评估,您可以通过针对str 的类型检查来保护math.isnan() 调用:

fn_list_to_check=[
    lambda x: x in ['nan', np.nan, ... ],
    lambda x: not isinstance(x, str),
    lambda x: math.isnan(x)
    ]

if any(f(x) for f in fn_list_to_check):
    # Do something
    pass

注意 any 中没有方列表括号,即 any() 而不是 any([])(谁知道?)。

我认为它非常出色但同样丑陋 - 选择你的毒药。

关于问题的第二部分(为什么是float('nan') != float('nan')),请参阅

What is the rationale for all comparisons returning false for IEEE754 NaN values?

【讨论】:

  • 如果x 是一个字符串,则math.isnan(x) 调用将引发TypeError。我们当然可以先检查它是否是字符串,但我希望找到更直接的方法
  • 在最坏的情况下你可以把它放在一个辅助函数中。
  • x is not str 似乎不对(检查x 是否不是字面上的类型(类)str)...也许您的意思是not isinstance(x, str)type(x) != str?跨度>
  • @Tomerikoo 是的 - 更正确 - 谢谢你
  • 现在我想知道一个过滤器链。
【解决方案3】:

为什么不直接将传递给math.isnan 的所有内容与另一个float 转换一起包装?如果它已经是一个浮点数(即float('nan')),您只需进行“冗余”调用:

import math

def is_nan(value):
    return math.isnan(float(value))

这似乎给了你预期的结果:

>>> is_nan(float('nan'))
True
>>> is_nan('nan')
True
>>> is_nan(np.nan)
True

【讨论】:

  • 它仍然适用于不是'nan' 的“其他字符串”?这不会抛出不同的TypeError吗?
  • @jtlz2 公平地说,在您根据您的回答更正我的评论后,您提供的两个代码都会有完全相同的问题...
  • Touché - 好地方:\
猜你喜欢
  • 2015-05-12
  • 2015-09-23
  • 2010-10-30
  • 2021-12-22
相关资源
最近更新 更多