Python 清洗 CSV 时的编码、空值与重复行处理实战
拿到一份别人导出的 CSV,第一反应不应该是直接读进分析,而是先做三件事:确认编码、看清空值、识别重复行。这三步做不好,后面的分组、求和、建模都会被悄悄带偏。下面用一份常见的订单 CSV 举例:字段包括订单号、用户、下单时间、商品、数量、金额、备注,数据来自人工导出和系统导出混合,问题很典型。
一、编码:先探测,不要猜
CSV 在 Windows 上常用 GBK 或 GB18030,在跨系统流转时又常是 UTF-8 带 BOM。直接用默认编码打开,轻则中文乱码,重则中途报错。稳妥的做法是先用少量字节探测:可以先以 UTF-8-SIG 尝试读取,失败再试 GB18030,并用 errors 参数做显式处理,而不是悄悄丢弃字符。更重要的是把结果固定下来:清洗脚本里写明最终统一转存为 UTF-8-SIG,这样下游 Excel 和 Python 都能正常打开,避免每次打开都要再猜一次。还要留意文件里的特殊字符,例如全角逗号、换行符被包在引号里、分隔符不一致,这些都会让行数对不上,读入后先核对行列数,再看前几行和尾几行。
二、空值:先分类,再决定怎么填
空值不等于缺失,也不等于零。订单表里,备注为空通常只是没有备注;金额为空可能是未结算,也可能是导出漏填;数量为空则不能直接当成 1。我的习惯是先统计每列空值数量和占比,再按业务含义分三类处理:第一类是确实不存在,例如备注、优惠券码,保留为空即可;第二类是可用规则补全,例如下单时间缺失但有支付时间、城市缺失但有收货地址中的城市,可以谨慎推导并记录推导规则;第三类是无法补全的关键字段,例如金额、数量缺失,就不要硬填平均值,先隔离成待核对数据,单独输出一份清单给业务方确认。pandas 里可以用 isna 统计,用 fillna 只对明确可填的列操作,关键列宁可保留空值并标注,也不要用 0 掩盖问题。
三、重复行:先判定什么是重复
重复行有两种:一种是整行完全相同,通常是导出时重复跑批造成的;另一种是业务主键重复,例如同一订单号出现两次,但金额或状态不同,这时不能直接删。处理前先确定主键:订单场景一般是订单号,明细场景是订单号加商品编号。用 duplicated 配合主键检查,先看重复行的数量和差异列,再决定策略。完全相同的行可以直接去重并保留一条;主键重复但内容不同,要按业务规则保留最新状态或金额最大的那条,并把被删除的行单独存档,而不是悄悄丢掉。去重后一定要复核:总行数、订单号唯一数、金额合计三项指标前后对比,确认去重没有误删有效订单。
四、一个可复用的清洗顺序
我推荐的顺序是:读入并固定编码,统一列名和空格,规范日期和数字类型,统计并分类空值,判定主键并去重,最后输出清洗报告。清洗报告至少包括原始行数、删除行数、空值处理记录、类型转换失败记录。这样别人拿到结果时能复现,也能在数据出问题时快速定位是源头问题还是清洗规则问题。
结语
CSV 清洗没有炫技的空间,价值就在于稳定和可复现。把编码写死、把空值分类、把重复行的判定标准写清楚,这份数据才真正能用于统计和决策。下次拿到一份陌生的 CSV,不妨先花十分钟做这三项检查,往往能省下后面几小时的返工。
- 点赞
- 收藏
- 关注作者
评论(0)