【第74期】填充后均值骤变:缺失、异常标记与清洗前后对照完整教程
系列:《从小白到 AI 大模型开发工程师的进阶之路》 技术点:AI-0234 缺失值与异常值 主人公:小蓝伞 前置:AI-0233 Pandas Series 与 DataFrame 本期产出:独立实验脚本、原始输出、失败样本和验收清单
小蓝伞在“缺失值与异常值”的教学实验中遇到一个容易被结果掩盖的问题:小蓝伞在合成金额表中将一千截为一百,均值从两百多降到二十多;数字变平稳,但大额真实事件也被改写。 缺失和异常是质量信号,不是自动删除指令。处理方案取决于产生机制、业务含义和下游目标,原始值与处理标记必须保留。
一、小蓝伞遇到的问题
缺失表示没有可用观测,异常表示偏离某条规则,两者可重叠也可独立。缺失还可能是业务不适用而不是采集失败。先写字段字典、允许范围和来源,再设质量规则;没有语义时把所有极端值删除,会混淆真实风险与错误数据。
二、先给结论
缺失和异常是质量信号,不是自动删除指令。处理方案取决于产生机制、业务含义和下游目标,原始值与处理标记必须保留。
推荐:识别后先标记,再按目标选择保留、隔离、填充或截断;学习型处理只在训练拟合。
不推荐:省略输入语义和指标口径,仅凭单次输出扩大结论。
成功判据:原一千仍保留;缺失标记数量1;训练中位数11、全量12;全缺失明确待处理。
三、任务与数据契约
| 项目 | 本期约定 |
|---|---|
| 输入 | 完整代码构造的合成数据 |
| 输出 | 数值、图表或异常及原始日志 |
| 环境 | Windows 11、Python 3.13.9,依赖见记录 |
| 不在范围 | 真实业务、生产容量和跨设备性能 |
四、前置准备
在新目录保存工作目录中的实验.py为main.py,再执行:
python -m venv .venv .\.venv\Scripts\python.exe -m pip install numpy==2.3.5 pandas==2.3.3 .\.venv\Scripts\python.exe main.py
本次实际执行使用 Windows 11、Python 3.13.9;代码只生成合成输入,不依赖账号、令牌或隐藏文件。
五、核心原理
缺失:当前没有可用观测。
异常:违反预先约定规则的观测。
填充:用声明规则替代缺失值。
截断:将超限值限制在边界。
审计列:记录原值与处理动作的字段。
保留原列与审计标记
实验保留原金额、来源、缺失标记、填充值、异常标记和截断值。用新列承载处理结果,让每条改动都能追溯。原始一千仍存在,因此需要回滚或重新评估阈值时可以恢复。只保存清洗后列会让后续团队不知道数字为什么变了。
填充器也会学习数据
训练金额十、十二的中位数为十一;加入测试一千后全量中位数变为十二。若预处理在全部数据上拟合,测试分布参与了训练。应先划分,再只用训练集拟合处理参数,并应用同一规则到其他集合。该顺序同样适用于缩放和特征选择。
全缺失列没有可估计中位数
全缺失列的中位数仍是缺失。用它填充不会真正产生有效值,必须选择有根据的外部默认、缺失指示或拒绝该字段。自动默认零也可能引入新语义。业务需要区分没有观察、确实零值和不适用,不能让一个数承担三种含义。
六、完整项目
完整脚本位于_work/第74期-缺失值与异常值/实验.py。它包含正常、边界和失败断言;复制到main.py后可独立运行。
import pandas as pd import numpy as np frame=pd.DataFrame({"amount":[10.,11.,None,1000.,12.],"origin":["normal","normal","missing","large_event","normal"]}) median=frame["amount"].median() frame["was_missing"]=frame["amount"].isna() frame["filled"]=frame["amount"].fillna(median) frame["suspect"]=frame["filled"]>100 frame["capped"]=frame["filled"].clip(upper=100) print(frame.to_string(index=False)) print("原始均值",frame["amount"].mean(),"填充均值",frame["filled"].mean(),"截断均值",frame["capped"].mean()) train=pd.Series([10.,12.,None]);test=pd.Series([1000.,None]) print("只用训练中位数",train.median(),"全量中位数",pd.concat([train,test]).median()) assert frame.loc[3,"amount"]==1000 and frame["was_missing"].sum()==1 all_missing=pd.Series([np.nan,np.nan]) print("全缺失中位数",all_missing.median(),"需要外部默认值或拒绝") 实现与结果的进一步核验
中位数的实际计算
原非缺失值十、十一、十二、一千排序,中间两值平均为十一点五,用于缺失填充。这个规则降低极端值对填充值的影响,却不删除原极端值,也不恢复未知真值。填充后指标是新数据的指标,报告应同时展示原缺失比例和所用规则。
截断保留了什么丢掉什么
把一千限制为一百保留超过阈值的方向信息,却抹掉实际大额幅度。某些模型可能从稳健处理受益,风险报告却可能需要原值。可以同时输出处理列和原值标记,按下游用途选择;不能用同一清洗列统一替代所有业务字段。
分组填充的条件
不同群体有不同水平时,全局中位数可能偏向大组。分组规则需足够样本、未知组回退和缺失组约定,还要防止目标泄漏。本文只运行全局小例,分组方案属于建议验证,不写成已测改进;提出方案时同时写失败条件才有工程意义。
质量报告的闭环
记录原行数、缺失数、标记数、实际改动数和改动后分布。异常标记不等于实际修改,每个动作都要有独立数量。若重跑后数量异常,先检查输入版本和阈值单位,不直接扩大过滤。质量报告也应和输出文件同一版本保存。
清洗顺序与回滚
先保留原始输入,定义规则,划分训练评价,再拟合参数、生成新列并检查。重跑应能够从原始数据恢复,而不是在上一次截断结果上继续截断。回滚恢复规则和处理参数也重要,只有恢复一个CSV不足以解释后续模型为什么变了。
七、可复现失败案例
全缺失中位数仍为NaN;全量拟合中位数污染测试;截断把真实大额事件改写。 这是构造的教学失败,不是线上事故。复现顺序是保存输入、运行脚本、记录输出、只改一个条件后重跑。修复后必须同时检查正常样本,不能用默认值掩盖错误。
八、实验设计与实际结果
原一千仍保留;缺失标记数量1;训练中位数11、全量12;全缺失明确待处理。 本次已经执行,退出状态为0;完整输出见工作目录。控制变量、样本量和参数写在脚本中。
amount origin was_missing filled suspect capped 10.0 normal False 10.0 False 10.0 11.0 normal False 11.0 False 11.0 NaN missing True 11.5 False 11.5 1000.0 large_event False 1000.0 True 100.0 12.0 normal False 12.0 False 12.0 原始均值 258.25 填充均值 208.9 截断均值 28.9 只用训练中位数 11.0 全量中位数 12.0 全缺失中位数 nan 需要外部默认值或拒绝
数字怎样对应本期机制
原始非缺失均值二百五十八点二五,中位数填充后均值二百零八点九,截断后为二十八点九。三个分母和数值集合都不同,不能把下降解释成业务改善。报告应比较数量、缺失、分布、尾部与改动记录,而不是只展示一个变好看的指标。
九、常见问题与排查顺序
先检查对象定义,再检查输入、形状、分母、索引或时间点,最后检查实现与环境。固定阈值易审计但依赖业务单位,分位数或稳健规则随分布变化,模型规则则增加维护成本。对每种方案报告误删和漏检案例,保留验证样本。本文只有手工合成数据,不承诺某阈值适用于真实订单;下一期聚合仍需保留清洗标记和分母。 不要把一次成功当成稳定性证明,也不要把技术指标直接换成业务价值。
十、系统与依赖差异
本次只在记录的 Windows 和库版本运行。浮点末位、计时、字体、编码和表格默认行为可能跨环境变化;未执行部分保持待核验。
十一、验证清单
执行脚本,核对退出状态与本篇实际输出。
重跑本篇正常、边界和失败样本,检查数值或拒绝结果。
更换数据时重新检查对象、分母和评价条件。
验收判据:原一千仍保留;缺失标记数量1;训练中位数11、全量12;全缺失明确待处理。
十二、面试题与追问
缺失在本期是什么?
答:当前没有可用观测。 缺失表示没有可用观测,异常表示偏离某条规则,两者可重叠也可独立。缺失还可能是业务不适用而不是采集失败。先写字段字典、允许范围和来源,再设质量规则;没有语义时把所有极端值删除,会混淆真实风险与错误数据。
追问:改变这个条件后,哪一个输出或失败判据应该变化?
异常在本期是什么?
答:违反预先约定规则的观测。 实验保留原金额、来源、缺失标记、填充值、异常标记和截断值。用新列承载处理结果,让每条改动都能追溯。原始一千仍存在,因此需要回滚或重新评估阈值时可以恢复。只保存清洗后列会让后续团队不知道数字为什么变了。
追问:改变这个条件后,哪一个输出或失败判据应该变化?
填充在本期是什么?
答:用声明规则替代缺失值。 原始非缺失均值二百五十八点二五,中位数填充后均值二百零八点九,截断后为二十八点九。三个分母和数值集合都不同,不能把下降解释成业务改善。报告应比较数量、缺失、分布、尾部与改动记录,而不是只展示一个变好看的指标。
追问:改变这个条件后,哪一个输出或失败判据应该变化?
截断在本期是什么?
答:将超限值限制在边界。 训练金额十、十二的中位数为十一;加入测试一千后全量中位数变为十二。若预处理在全部数据上拟合,测试分布参与了训练。应先划分,再只用训练集拟合处理参数,并应用同一规则到其他集合。该顺序同样适用于缩放和特征选择。
追问:改变这个条件后,哪一个输出或失败判据应该变化?
审计列在本期是什么?
答:记录原值与处理动作的字段。 全缺失列的中位数仍是缺失。用它填充不会真正产生有效值,必须选择有根据的外部默认、缺失指示或拒绝该字段。自动默认零也可能引入新语义。业务需要区分没有观察、确实零值和不适用,不能让一个数承担三种含义。
追问:改变这个条件后,哪一个输出或失败判据应该变化?
十三、工程判断与下一期
识别后先标记,再按目标选择保留、隔离、填充或截断;学习型处理只在训练拟合。 下一期为AI-0235 分组、聚合与透视。本期保留的契约和反例会继续使用。
从本地证据到实际决策
删除样本改变谁被统计
如果异常恰是某群体或高额事件,删除会改变总体,均值改善也可能来自选择。删除前报告数量、比例和相关类别,删除后保留排除理由。缺失行同样不应自动消失,业务不适用与采集故障的处理策略可能不同。
用新列比较而非覆盖
原值、填充值和截断值并列,读者可以按行看到哪些值变动。脚本还保留来源字段,确认一千代表构造的真实大额事件。真正错误录入可以修正,但需要来源证据;仅凭阈值无法判断真伪,标记应该先于修改。
阈值漂移的维护
数据单位变化或业务增长后固定一百阈值可能标记更多正常事件。分位数规则也会随窗口改变,不能不记录窗口和参数。质量系统应保存版本,比较标记率和处理后分布,出现突变先核对输入而非直接提高阈值。
模型清洗的评价隔离
在训练集拟合的中位数应用到测试,是隔离要求;若根据测试分数选择阈值,仍参与模型选择。完整流程要保护拟合和调参,不只是把某个fit调用放到训练文件。下期统计报告亦需要指出使用原列还是处理列。
全缺失的方案条件
外部默认值需有业务依据,删除列需说明后续字段依赖,保留缺失标记需模型支持。三种方案不能在无信息时自动宣布最优。当前脚本返回NaN揭露这个边界,作者应记录待决策而非隐藏警告或编造填充值。
不要把填充值当成真实观测
填充的十一点五不是从来源恢复的原金额,而是指定规则产生的估计。后续若评估观测质量,应继续保留was_missing标记;若统计填充后指标,应说明它包含合成值。实际审计可按原始非缺失与处理结果分别输出,让读者区分业务变化和处理变化。相同规则再次运行应保持可重建,不能在已处理结果上无记录地叠加。
官方资料
Working with missing data — pandas 3.0.6 documentation:用于核对本期技术机制或接口,查阅日期为2026-10-13。
适用边界
只覆盖脚本中的合成数据、明确假设和已记录版本。真实业务需追加授权、监控、资源预算、回滚和领域验证。