np.nan_to_num 默认将 np.nan 替换为 0.0,np.inf 替换为 dtype 对应的 finfo.max(如 float64 下约 1.798e308),-np.inf 替换为 finfo.min。
np.nan_to_num 默认把 np.nan 替换成 0.0,把 np.inf 替换成当前浮点类型的极大值(如 np.finfo(float).max),-np.inf 替换成极小值(np.finfo(float).min)。这不是“截断”或“丢弃”,而是有明确数值映射的填充。
常见误解是它只管 nan,其实 inf 类型默认也参与转换——这点容易被忽略,尤其在做数据清洗时误以为 inf 会保留原样。
np.nan_to_num(x, nan=0.0, posinf=None, neginf=None),其中 posinf 和 neginf 为 None 时才触发极值替换posinf=1e308,则 np.inf 被替换成 1e308,不再用 finfo.max
posinf=np.nan,那 np.inf 反而变成 nan,后续可能被二次处理当 posinf 或 neginf 为 None(即未指定),np.nan_to_num 会查当前 dtype 的 finfo。对 float64,np.finfo(np.float64).max ≈ 1.798e308;对 float32,则是 ≈ 3.403e38。这些值不是 magic number,而是 IEEE 754 规定的可表示最大有限值。
关键点:这个替换发生在“数值域内”,不引发 overflow(因为本身就是上限),但下游计算若再做乘法或指数运算,仍可能立刻溢出为 inf。
np.finfo(x.dtype).max,别硬记常量float32 和 float64)会先 upcast,再取对应 finfo
inf(本身不能存 inf),但 nan 会报错,需先转 float最常见原因是:你传入的是整数数组,或数组里根本没 inf,但你以为有;或者你用了旧版 NumPy(posinf/neginf 参数尚未支持 None 默认行为(那时默认不处理 inf)。
另一个隐蔽原因:输入含 Python 原生 float('inf'),但数组 dtype 是 object ——此时 np.nan_to_num 不递归处理 object 元素,直接返回原数组。
x.dtype,非 object 且为浮点型才有效np.isinf(x).any(),别靠 print 猜np.nan_to_num(x, nan=0.0, posinf=1e308, neginf=-1e308)
如果目标只是“去掉异常值用于绘图或统计”,用 np.nan_to_num 可能掩盖问题——把 inf 塞进一个极大但合法的数,mean、std 会被严重扭曲。这时候更稳妥的是显式掩码或截断。
例如,用 np.clip 限定范围,或用布尔索引清空:x[np.isinf(x)] = np.nan 再统一处理;又或者用 scipy.stats.mstats.trim 避开极端值。
np.nan_to_num 适合“快速兜底 + 进入下游数值计算流程”的场景,比如喂给 sklearn 模型前的预处理np.isnan(x) | np.isinf(x) 再操作