Python 现代开发学习笔记

(十三)缺失数据与数值精度

1. 缺失记录不按零参与平均

缺失时长与阅读了 0 分钟是不同记录。浮点数组可以用 np.nan 标记缺失,用 isnan 识别;无穷值又是另一类结果,isfinite 统一选出普通有限数。

# 项目文件:demos/missing_precision.py
# 缺失值不是零;先核对有效项,再决定这一项是否参与统计。
import numpy as np

values = np.array([10.0, np.nan, 30.0, np.inf])
valid = np.isfinite(values)
print("有效项", valid.tolist(), values[valid].mean())
print("识别缺失", np.isnan(values).tolist())
print("只忽略NaN仍有无穷", np.nanmean(values))
print("忽略缺失", np.nanmean(np.array([10.0, np.nan, 30.0])))
print("小数相等", 0.1 + 0.2 == 0.3, bool(np.isclose(0.1 + 0.2, 0.3)))
large = np.array([100000000, 1, -100000000], dtype=np.float32)
print("累计精度", large.sum().item(), large.sum(dtype=np.float64).item())

[10,nan,30,inf] 中的有效项为 [10,30],平均数为 20。nanmean 只忽略 NaN,保留 inf 后结果仍为无穷;先核对哪些数参与计算,再确定统计过程。若一组全是缺失值,就先在数据清洗时记录这个状态,不凭空补成零。

四项记录逐项判断有限性,只有10和30进入统计,缺失和无穷各自保留原因

2. 舍入误差出现在中间步骤

二进制浮点数对 0.1 等小数只能近似保存,所以 0.1+0.2==0.3 为 False。isclose 根据绝对与相对容差比较接近程度;例如检查接近零的误差时,可以明确设置 atol=1e-10,rtol=0,让检查表达实际关心的精度。

float32 的 [100000000,1,-100000000] 按示例累计得到 0,而把 sum 的累计 dtype 设为 float64 后得到 1。较小的 1 在前一次 float32 相加时已经被舍入,最后的大数相消不会把它找回来。

先把一加进一亿时float32丢掉小量,随后相消得到零,较宽累计保留小量得到一

笔记正文与全部题解 · Ctrl / ⌘ K