pandas 3.0.1 数据清洗实测:两个旧示例报错与 14 项结果校验
数据清洗教程里最容易被忽略的前提,是示例究竟使用了哪个依赖版本。2026 年 11 月 2 日,参考华为云 KooLabs 的“Python 数据分析-pandas 数据清洗”实验手册,在本地使用合成数据复现了主要的数据清洗操作,同时检查了旧示例在 pandas 3.0.1 下的行为。
本文由 AI 助手协助编写、运行示例并整理结果。示例不含真实用户或业务数据;运行环境为 Python 3.12.14、pandas 3.0.1、NumPy 2.3.5。本文只记录本地数据处理实践,不代表完成了手册中的 ECS 购买、云端部署或认证考试,也不代表账号所有者已逐项人工验收。
一、前向填充:旧参数会直接报错
在上述环境中运行:
import numpy as np
import pandas as pd
s = pd.Series([1.0, np.nan, 3.0])
s.fillna(method="ffill")
实际报错为:
TypeError: NDFrame.fillna() got an unexpected keyword argument 'method'
使用专门的方法可以表达同样的意图:
assert s.ffill().tolist() == [1.0, 1.0, 3.0]
assert s.bfill().tolist() == [1.0, 3.0, 3.0]
assert s.interpolate().tolist() == [1.0, 2.0, 3.0]
这里需要先明确业务规则:前向填充沿用上一个已知值,后向填充采用后一个已知值,线性插值则估计中间值。三者能运行,并不意味着可以在业务上随意互换。数据若按时间排序、分组方式不同,填充结果也可能产生不同含义。
二、插值:先限定数值列
另一个实测问题出现在混合字符串和数值的表格上:
df = pd.DataFrame({
"label": ["a", "b", "c"],
"value": [1.0, np.nan, 3.0],
})
df.interpolate()
在本次 pandas 3.0.1 环境中,结果是:
TypeError: Cannot interpolate with str dtype
更清晰的处理方式是只对需要插值的数值列操作:
numeric = df.select_dtypes(include="number").columns
df[numeric] = df[numeric].interpolate()
assert df["value"].tolist() == [1.0, 2.0, 3.0]
assert df["label"].tolist() == ["a", "b", "c"]
不要为了让插值函数通过,就把标识符、标签或日期原文随意转成数字。清洗应该保留字段语义,而不是只追求代码没有异常。
三、把清洗规则写成可以检查的结果
这次实践使用独立构造的订单、分组和时间数据,共完成 14 项校验:
| 检查内容 | 实测结果或不变量 |
|---|---|
| 缺失值检测 | customer 和 amount 各有 1 个缺失值 |
| 删除缺失行 | 5 行保留 4 行 |
| 中位数填充 | 缺失金额填为 40.0 |
| 前填、后填、插值 | 中间值分别为 1.0、3.0、2.0 |
| 重复值处理 | 5 行去重后为 4 行 |
| 类型转换 | 分别识别 1 个非法数值、日期和未知布尔值 |
| 字符串规范化 | 去空格并统一大小写,保留缺失值 |
| 替换与映射 | 等级准确映射为说明文字 |
| IQR 异常值处理 | 识别异常值 150,截断结果全部落在边界内 |
| 分箱 | 三个等频分组各有 2 个值 |
| 归一化与标准化 | 最小最大值为 0、1;样本标准差为 1 |
| 日期时间处理 | 正确提取天数差,非法日期继续保持缺失 |
| 数据合并 | inner、left、outer 分别返回 2、3、4 行 |
| 宽长表转换 | 转换后再还原,与原表一致 |
所有校验在本地运行通过。断言的价值,是把“看起来清洗好了”改成明确的约束。例如,合并后行数意外增加,可能意味着关联键不唯一;因此示例使用 validate="one_to_one" 检查关联关系。实际业务若本来就是一对多,应选用对应约束,不能照搬。
四、转换失败后,不要把问题藏起来
raw = pd.Series(["12.50", "bad", "4"])
converted = pd.to_numeric(raw, errors="coerce")
invalid = raw.notna() & converted.isna()
assert invalid.sum() == 1
assert raw[invalid].tolist() == ["bad"]
errors="coerce" 只是把不可解析的内容转换为缺失值,不等于修复了原始数据。保留非法值数量和原始值,才能继续判断应当纠正、隔离还是拒收。业务主键、金额和时间字段尤其应该定义明确的处理规则。
五、复现实验时保留三个边界
第一,记录依赖版本,升级后重新执行关键用例。本文的兼容性结论仅对应上述实测环境,不推断其他版本也有完全相同的表现。
第二,使用合成数据验证流程,再在授权范围内接入业务数据。填充、去重和异常值截断都可能改变统计结论,需要业务规则支持。
第三,把本地代码实践与云资源操作分开记录。这次运行没有购买 ECS,也没有调用付费模型 API;不能把本地断言通过描述成云端部署已经完成。
参考实验手册:https://edu.huaweicloud.com/lab/experiment-detail_20006973
文中代码是针对上述问题重新整理的最小示例;表中结果来自本次实际运行记录。
- 点赞
- 收藏
- 关注作者
评论(0)