恼人的NaN (Not a Number)
2019-03-02 本文已影响0人
SunshineDrizzle
简介
NaN的全称是Not a Number,意思是“不是一个数字”,它用于代表那些未定义或是不可表征的值。比如在数值运算时遇到分母为0的情况,其结果往往会用NaN来代替。下面我主要针对Python中的NaN的性质进行探讨。
创建NaN
虽然不是一个数,但NaN属于浮点数类型。
>>> import math
>>> import numpy as np
>>> math_nan = math.nan
>>> np_nan = np.nan
>>> float_nan = float('nan')
>>> isinstance(math_nan, float) and isinstance(np_nan, float) and isinstance(float_nan, float)
>>> True
这里介绍了三种方法,其中前两种其实只是分别对两个库各自预先定义的NaN进行引用,第三种方法会创建新的NaN(开辟新的内存空间)。
>>> math_nan is math_nan and np_nan is np.nan
>>> True
>>> math_nan is np_nan or float_nan is float('nan')
>>> False
检测NaN
由于NaN是未被定义的值,所以它无所谓大小或是相等。
>>> math_nan==math_nan or np_nan>np_nan or float_nan<float_nan
>>> False
>>> math_nan!=math_nan and np_nan!=np_nan and float_nan!=float_nan
>>> True
所以要想用关系运算来检测NaN,需要通过自身不等于自身这一点来实现。当然用python库自带的检测会更好理解以及让人放心。
>>> math.isnan(math_nan) and math.isnan(np_nan) and math.isnan(float_nan)
>>> True
>>> np.isnan(math_nan) and np.isnan(np_nan) and np.isnan(float_nan)
>>> True
应对NaN
NaN的存在有时会影响计算,除了一开始避免产生NaN,对于一些无法避免的,我们首先就是要能检测到它,然后根据我们的需求做出相应处理。比如在求平均的时候忽略NaN,或是把NaN转化成不影响后续步骤的值。
>>> np.mean([1, np_nan, 3])
>>> nan
>>> np.nanmean([1, np_nan, 3])
>>> 2.0
>>> np.nan_to_num(np_nan)
>>> 0.0