numpy中检测异常值需组合使用np.isnan()和np.isinf():前者仅对浮点数有效,后者捕获±inf;推荐has_bad = np.isnan(arr).any() or np.isinf(arr).any(),避免typeerror与误判。

用 np.isnan() 和 np.isinf() 分别检查
NumPy 不提供“一键检测所有异常值”的函数,但 np.isnan() 和 np.isinf() 是最直接、开销最小的手段。它们返回布尔数组,需配合 .any() 才能快速得到标量结果。
-
np.isnan(arr)只对float类型有效;整数数组或字符串数组调用会静默返回全False,不报错但结果无意义 -
np.isinf(arr)同样只作用于浮点数,且会同时捕获np.inf和-np.inf - 若数组含多种 dtype(如结构化数组),需先确认字段类型,否则布尔索引可能出错
一行判断:组合 np.isnan() + np.isinf()
实际项目中通常要同时排除 NaN 和无穷值,推荐写成:
has_bad = np.isnan(arr).any() or np.isinf(arr).any()
注意不能写成 np.isnan(arr) | np.isinf(arr) 再调用 .any() —— 这会在整数数组上触发 TypeError: ufunc 'isnan' not supported for the input types,因为 np.isnan() 对非浮点类型不兼容。
- 如果确定
arr是浮点型(arr.dtype == np.float64等),可用更紧凑写法:has_bad = np.any(np.isnan(arr) | np.isinf(arr))
- 对大型数组,
.any()有短路行为(找到第一个True就停),比np.sum()或np.count_nonzero()更快
避免误判:注意 np.nan 的特殊比较行为
np.nan != np.nan 恒为 True,所以绝不能用 arr == np.nan 或 arr != np.nan 来检测 NaN —— 这会返回全 False 数组。
- 同理,
arr is np.nan也无效,因为np.nan是个对象,数组元素是值而非引用 - 曾有人用
np.where(arr != arr)做 NaN 检测,虽在数值上等价于np.isnan(),但可读性差、易被误读,且不处理无穷值 - 若从 Pandas 导入数据,记得
pd.isna()能统一处理 NaN、None、NaT,但 NumPy 原生数组不认None
性能敏感时:优先用 np.any(),慎用 np.sum()
对上亿元素的数组,np.any(np.isnan(arr)) 平均耗时比 np.sum(np.isnan(arr)) > 0 低一个数量级,尤其当异常值靠前时。
-
np.any()是 C 层短路实现;np.sum()必须遍历全部元素 - 不要为了“看起来更函数式”而写
np.count_nonzero(np.isnan(arr)) > 0,它和np.sum()一样无短路 - 如果后续还需知道有多少个 NaN,再考虑
np.count_nonzero(),否则纯判断场景一律用.any()
float64 并填 np.nan,但你自己用 np.loadtxt() 且没设 dtype=float,就可能拿到整数数组——此时 np.isnan() 完全失效,却不会报错。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











