Python中list.count(nan)计数不可靠且无告警是什么原因?
Python中使用list.count统计nan结果不符合预期问题说明
问题描述
我有一个存储数值的列表,其中部分损坏值使用nan表示。对数据进行处理后,nan按预期规则正常传播。后续我需要统计处理后数据集中的无效值数量,直觉上调用了.count(nan)方法,却意外发现该方法仅会统计未经过运算的原始nan,且运行过程中没有任何告警提示。
我在Python官方文档的math.nan说明页未找到相关解释,同时list.count(x)方法的文档描述也不够精准,仅说明“返回x在列表中出现的次数”。
复现代码
from math import nan, isnan list1 = [nan] myitem1 = list1[0] myitem2 = list1[0] + 1 # 常见操作:从列表中提取值后做运算 print(myitem2) # 输出 nan:外观上是nan print(isnan(myitem2)) # 输出 True:本质确实是nan list2 = [1, nan, myitem1, myitem2] count1 = list2.count(nan) count2 = sum(isnan(e) for e in list2) print(count1, count2) # 输出 2, 3:说明count方法没有统计到所有nan
原因解析
- 这是IEEE 754浮点数标准的规定:
nan作为特殊浮点数,和任何值做相等判断都会返回False,包括和它自身比较,即nan == nan的结果永远为False。 - Python的
list.count(x)的底层匹配逻辑为:遍历列表内每个元素,先判断元素是否和x为同一对象(elem is x),如果身份匹配就直接计入统计;身份不匹配的情况下才会判断elem == x是否为真,为真才计入统计。 - 经过运算产生的新
nan是独立的浮点数对象,和导入的math.nan不是同一个对象,既不满足身份匹配,也不满足相等判断匹配,因此不会被list.count(nan)统计到,只有直接引用同一个原始nan对象的元素才会被计数。
正确用法
统计列表中nan的数量时,不要使用list.count方法,改用math.isnan逐个判断元素即可:
from math import isnan nan_total = sum(isnan(item) for item in target_list)
如果是处理numpy数组的场景,可以使用np.count_nonzero(np.isnan(arr))实现更高效率的统计。
内容的提问来源于stack exchange,提问作者sch
相关产品推荐
相关产品推荐

