如何检测数据中的异常数值(NaN、Infinity、None等)

16次阅读

如何检测数据中的异常数值(NaN、Infinity、None等)

本文介绍在数据管道验证中高效识别异常数值(如 nan、inf、-inf、none)的实用方法,涵盖 python 原生与 numpy 双方案,强调 `math.isfinite()` 的核心作用,并指出常见误区与最佳实践。

在构建健壮的数据处理流水线时,确保数值字段“干净”是关键一步。仅靠范围校验(如 x ∈ [-10, 10])无法捕获非有限值(non-finite values)——例如 Float(‘nan’)、float(‘inf’)、float(‘-inf’),以及 None 或其他非数字类型(如字符串 ‘missing’)。这些值虽能通过部分算术运算“存活”,却极易在后续统计、模型训练或序列化中引发静默错误或崩溃。

推荐的核心判断逻辑是:
isinstance(x, (int, float)) and math.isfinite(x)

⚠️ 注意:math.isfinite(x) 已隐式排除 NaN 和 ±Inf(即 math.isfinite(nan) == False,math.isfinite(float(‘inf’)) == False),因此无需额外调用 math.isnan()。该函数是 python 标准库中专为数值健全性设计的权威判定工具

以下是两种典型使用场景的实现:

1. 批量校验整个数据集(返回布尔结果)

import math  def all_numbers_valid(data):     """检查所有元素是否为有效的有限浮点数或整数"""     return all(         isinstance(x, (int, float)) and math.isfinite(x)         for x in data     )  # 示例 print(all_numbers_valid([1, -3.14, 0, 100]))        # True print(all_numbers_valid([1, 2, float('nan')]))       # False print(all_numbers_valid([1, None, 3]))               # False(None 不是 int/float) print(all_numbers_valid([1, '2', 3]))                # False(字符串 '2' 不是数值类型)

2. 逐项诊断并定位异常值

def find_invalid_entries(data):     """返回所有无效值及其索引,便于调试与日志记录"""     invalid = []     for i, x in enumerate(data):         if not (isinstance(x, (int, float)) and math.isfinite(x)):             invalid.append((i, repr(x), type(x).__name__))     return invalid  # 示例 data = [1.0, float('inf'), None, -5, float('nan'), "99"] invalids = find_invalid_entries(data) for idx, val_repr, typ in invalids:     print(f"Index {idx}: {val_repr} ({typ})")   # 输出: # Index 1: inf (float) # Index 2: None (NoneType) # Index 4: nan (float) # Index 5: '99' (str)

? 重要补充说明:

  • numpy 用户可选用 np.isfinite(),它对数组更高效,且自动广播、支持 pd.Series/np.ndarray;但注意:np.isfinite(None) 会报错,务必先做类型过滤或用 pd.isna() 配合。
  • None、np.nan、float(‘nan’) 三者语义不同:None 是 Python 空对象;np.nan 是 NumPy 的 NaN 表示;float(‘nan’) 是内置浮点 NaN。math.isfinite() 对后两者均返回 False,但对 None 会抛 TypeError —— 因此 isinstance(…) 类型检查必不可少。
  • ❌ 错误做法:仅用 x != x 判 NaN(不覆盖 Inf)、或 x is not None(忽略 NaN/Inf)、或 abs(x)

? 总结建议:
将 isinstance(x, (int, float)) and math.isfinite(x) 作为数值有效性校验的黄金标准;在 etl 或特征工程入口处统一调用,配合清晰的错误上下文输出,可大幅提升数据质量监控的可靠性与可维护性。

text=ZqhQzanResources