关于Python中Inf与Nan的判断问题详解


Posted in Python onFebruary 08, 2017

大家都知道 在Python 中可以用如下方式表示正负无穷:

float("inf") # 正无穷
float("-inf") # 负无穷

利用 inf(infinite) 乘以 0 会得到 not-a-number(NaN) 。如果一个数超出 infinite,那就是一个 NaN(not a number)数。在 NaN 数中,它的 exponent 部分为可表达的最大值,即 FF(单精度)、7FF(双精度)和 7FFF(扩展双精度)。 NaN 数与 infinite 数的区别是:infinite 数的 significand 部分为 0 值(扩展双精度的 bit63 位为 1);而 NaN 数的 significand 部分不为 0 值。

我们先看看如下的代码:

>>> inf = float("inf")
>>> ninf = float("-inf")
>>> nan = float("nan")
>>> inf is inf
True
>>> ninf is ninf
True
>>> nan is nan
True
>>> inf == inf
True
>>> ninf == ninf
True
>>> nan == nan
False
>>> inf is float("inf")
False
>>> ninf is float("-inf")
False
>>> nan is float("nan")
False
>>> inf == float("inf")
True
>>> ninf == float("-inf")
True
>>> nan == float("nan")
False

如果你没有尝试过在 Python 中判断一个浮点数是否为 NaN,对以上的输出结果肯定会感到诧异。首先,对于正负无穷和 NaN 自身与自身用 is 操作,结果都是 True,这里好像没有什么问题;但是如果用 == 操作,结果却不一样了, NaN 这时变成了 False。如果分别用 float 重新定义一个变量来与它们再用 is 和 == 比较,结果仍然出人意料。出现这种情况的原因稍稍有些复杂,这里就不赘术了,感兴趣可以查阅相关资料。

如果你希望正确的判断 Inf 和 Nan 值,那么你应该使用 math 模块的 math.isinf math.isnan 函数:

>>> import math
>>> math.isinf(inf)
True
>>> math.isinf(ninf)
True
>>> math.isnan(nan)
True
>>> math.isinf(float("inf"))
True
>>> math.isinf(float("-inf"))
True
>>> math.isnan(float("nan"))
True

这样便准确无误了。既然我在谈论这个问题,就是再忠告:不要在 Python 中试图用 is 和 == 来判断一个对象是否是正负无穷或者 NaN。你就乖乖的用 math 模块吧,否则就是引火烧身。

当然也有别的方法来作判断,以下用 NaN 来举例,但仍然推荐用 math 模块,免得把自己弄糊涂。

用对象自身判断自己

>>> def isnan(num):
...  return num != num
... 
>>> isnan(float("nan"))
True

用 numpy 模块的函数

>>> import numpy as np
>>> 
>>> np.isnan(np.nan)
True
>>> np.isnan(float("nan"))
True
>>> np.isnan(float("inf"))
False

Numpy 的 isnan 函数还可以对整个 list 进行判断:

>>> lst = [1, float("nan"), 2, 3, np.nan, float("-inf"), 4, np.nan]
>>> lst
[1, nan, 2, 3, nan, -inf, 4, nan]
>>> np.isnan(lst)
array([False, True, False, False, True, False, False, True], dtype=bool)

这里的 np.isnan 返回布尔值数组,如果对应位置为 NaN,返回 True,否则返回 False。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Python 相关文章推荐
Python远程桌面协议RDPY安装使用介绍
Apr 15 Python
python:socket传输大文件示例
Jan 18 Python
Python实现将SQLite中的数据直接输出为CVS的方法示例
Jul 13 Python
详解python里使用正则表达式的全匹配功能
Oct 19 Python
python读文件保存到字典,修改字典并写入新文件的实例
Apr 23 Python
python实现根据指定字符截取对应的行的内容方法
Oct 23 Python
Python中new方法的详解
Jan 15 Python
Pyinstaller打包.py生成.exe的方法和报错总结
Apr 02 Python
FFT快速傅里叶变换的python实现过程解析
Oct 21 Python
python生成并处理uuid的实现方式
Mar 03 Python
Python 读取位于包中的数据文件
Aug 07 Python
分享3个非常实用的 Python 模块
Mar 03 Python
python3.5实现socket通讯示例(TCP)
Feb 07 #Python
Python中字典的setdefault()方法教程
Feb 07 #Python
Python连接数据库学习之DB-API详解
Feb 07 #Python
使用Python中的tkinter模块作图的方法
Feb 07 #Python
Scrapy-redis爬虫分布式爬取的分析和实现
Feb 07 #Python
详解python中字典的循环遍历的两种方式
Feb 07 #Python
python3使用PyMysql连接mysql数据库实例
Feb 07 #Python
You might like
php抽奖小程序的实现代码
2013/06/18 PHP
关于Sphinx创建全文检索的索引介绍
2013/06/25 PHP
简单解决新浪SAE无法上传文件的问题
2015/05/13 PHP
PHP发送短信代码分享
2015/08/11 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
PHP $O00OO0=urldecode & eval 解密,记一次商业源码的去后门
2020/09/13 PHP
jquery 模板的应用示例
2013/11/12 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
浅谈javascript中return语句
2015/07/15 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
jQuery extend()详解及简单实例
2017/05/06 jQuery
JavaScript实现跟随滚动缓冲运动广告框
2017/07/15 Javascript
JS实现前端缓存的方法
2017/09/21 Javascript
vue的token刷新处理的方法
2018/07/17 Javascript
详解适配器在JavaScript中的体现
2018/09/28 Javascript
微信小程序实现的一键复制功能示例
2019/04/24 Javascript
基于js实现抽红包并分配代码实例
2019/09/19 Javascript
JS代码实现页面切换效果
2021/01/10 Javascript
[19:54]夜魇凡尔赛茶话会 第一期02:看图识人
2021/03/11 DOTA
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
python开发之IDEL(Python GUI)的使用方法图文详解
2015/11/12 Python
python爬取网页转换为PDF文件
2018/06/07 Python
使用Python来开发微信功能
2018/06/13 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
Python Unittest根据不同测试环境跳过用例的方法
2018/12/16 Python
Python如何对齐字符串
2020/07/30 Python
pycharm 2020.2.4 pip install Flask 报错 Error:Non-zero exit code的问题
2020/12/04 Python
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
abstract class和interface有什么区别?
2012/01/03 面试题
预备党员期盼十八届四中全会召开思想汇报
2014/10/17 职场文书
小学生安全教育主题班会
2015/08/12 职场文书
《我的伯父鲁迅先生》教学反思
2016/02/16 职场文书
2019暑假学生安全口号
2019/06/27 职场文书
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers