首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >#WorkBuddy# 18 个分表 2.7 万行,我把"多表合并"跑成一条带 6 类校验的流水线

#WorkBuddy# 18 个分表 2.7 万行,我把"多表合并"跑成一条带 6 类校验的流水线

原创
作者头像
用户12784192
修改于 2026-09-29 08:07:28
修改于 2026-09-29 08:07:28
250
举报

一、痛点:合并后的表,谁也不敢用

多部门、多门店各交一张月度报表,最后要合成一张总表——这是所有做数据的人最常见的起点。难点从来不是"合",而是合完之后没人敢为这张表签字:同一个字段在 A 表叫「金额」、B 表叫「总价」、C 表叫 amount;日期有 2026/08/01 也有 20260801;单号重复、金额对不上、客户名空白……你不知道里面藏着多少坑,只能祈祷。

在 WorkBuddy 里我让 AI 直接动手验证了这个场景:先用程序合成 18 个 xlsx 分表(26,954 行,故意注入了重复、缺失、勾稽错误、非法值、跨表冲突五类脏数据),再写一条治理式合并流水线跑真实对比。所有数字都是实测出来的,可复现。

二、根因:pd.concat 只解决"拼起来",不解决"可信"

根因分析只有一句话:pd.concat 是物理拼接,它默认所有表的列语义一致。而现实是表头漂移、格式漂移、口径漂移三件事必然发生。所以对照组(直接 concat)跑完的结果是:23 列、40 万个空单元格、0 条校验、0 个问题——它不会报错,这才是最大的错。

三、实测对比:同一批数据,两种跑法

指标

pd.concat 一把梭

治理式合并 + 校验

合并后列数

23 列(表头各写各的)

8 列 + 来源标记

空单元格

404,642 个

业务必填列全部核对

校验规则

0 条

6 条

发现问题

0 处(静默通过)

1,277 处

去重后行数

26,954

26,792(剔除 162 行完全重复)

干净可用行数

—

26,216(隔离 576 行,隔离率 2.15%)

耗时

2.82 s

3.14 s

最扎眼的是金额:全部行合计 ¥252,341,849.90,干净行合计 ¥246,802,692.06,差额 ¥5,539,157.84。也就是说,如果不做校验直接把总表交给下游,大约 553 万元的错数会一路流进报表。

四、可复制代码

核心逻辑五十行以内:列名归一 → 数值/日期清洗 → 六条规则逐条命中 → 命中行隔离落盘。

代码语言:python
复制
import glob, re, unicodedata
import pandas as pd
from datetime import datetime

HEADER_MAP = {"订单编号":"order_id","订单号":"order_id","order_id":"order_id",
              "下单日期":"order_date","日期":"order_date","date":"order_date",
              "商品编码":"sku","SKU":"sku","货号":"sku",
              "数量":"qty","件数":"qty","qty":"qty",
              "单价":"price","price":"price",
              "金额":"amount","总价":"amount","amount":"amount","total":"amount",
              "客户名称":"customer","客户":"customer",
              "订单状态":"status","状态":"status"}
DATE_FMTS = ["%Y-%m-%d","%Y/%m/%d","%Y%m%d","%d-%m-%Y"]

def norm(s):
    s = unicodedata.normalize("NFKC", str(s)).strip().lower()
    return HEADER_MAP.get(s, s)

frames = []
for f in glob.glob("./raw/*.xlsx"):
    df = pd.read_excel(f, dtype=object)
    df.columns = [norm(c) for c in df.columns]
    df["__src"] = f
    frames.append(df)
m = pd.concat(frames, ignore_index=True, sort=False)

def num(v):
    s = str(v).replace("¥","").replace(",","").strip()
    try: return round(float(s), 2)
    except Exception: return None

def pdate(v):
    for f in DATE_FMTS:
        try: return datetime.strptime(str(v).strip(), f)
        except Exception: pass
    return None

m["amount"] = m["amount"].map(num)
m["price"]  = m["price"].map(num)
m["qty"]    = m["qty"].map(num)
m["order_date"] = m["order_date"].map(pdate)

# 规则1:完全重复行
dup = m.duplicated(keep="first")
clean = m[~dup].copy()
# 规则2:金额勾稽 qty*price == amount
clean["calc"] = (clean["qty"]*clean["price"]).round(2)
bad_amt = clean[(clean["amount"]-clean["calc"]).abs() > 0.01]
# 规则3:必填缺失
miss = clean[["order_id","sku","qty","price","amount"]].isna().any(axis=1)
# 规则4:非法值(负数量 / 坏日期)
inv = (clean["qty"] <= 0) | clean["order_date"].isna()
# 规则5:跨表冲突(同单号多来源且金额不一致)
g = clean.groupby("order_id").agg(n_src=("__src","nunique"), n_amt=("amount","nunique"))
conf = g[(g["n_src"]>1) & (g["n_amt"]>1)]

clean[~(miss | inv | clean["order_id"].isin(conf.index))].to_excel("merged_clean.xlsx")

五、踩坑清单

全角/半角是大坑:SKU、¥、千分位逗号都得先过 unicodedata.normalize("NFKC") 再清洗,否则金额列一转 float 就整列变 NaN。 日期别只认一种格式:18 张表里实测出 4 种写法,多格式循环解析 + 解析失败打标记,比强制 to_datetime 稳。 去重要分两步:完全重复行(整行一样)先去掉,同单号多行但内容不同的留给跨表冲突规则去判断,直接 drop_duplicates(subset="订单号") 会把真冲突一起吞掉。 金额勾稽不要用 ==:浮点误差会让大量正常行误报,阈值放到 0.01 即可。 坏行不要删,要隔离:命中规则的行单独写进 quarantine 表,下游有人质疑时每一条都能拿出来对质,这比"干净"更重要。 顺手加一列 __src 记录来源文件,排查跨表冲突时能直接定位到"哪两个门店报的不一致"。

六、给 WorkBuddy 的提示词模板

我有 18 个 xlsx 分表(路径 ./raw),表头和格式不一致。请写一条 Python 流水线:① 建列名映射字典归一表头;② 金额/数量清洗(去 ¥、千分位);③ 日期多格式解析,失败打标;④ 依次校验:完全重复行、金额勾稽(数量×单价 与金额差 >0.01)、必填缺失、非法值(负数量/坏日期)、跨表冲突(同单号多来源且金额不一致);⑤ 命中行写 merged_quarantine.xlsx,干净行写 merged_clean.xlsx;⑥ 最后输出一张命中统计表和干净/隔离行数,每个数字都要真实跑出来,不许估算。

把这段话丢给 WorkBuddy,它会自己生成数据集、写脚本、跑批、核对输出——本次实测从读入到出报告 3.14 秒,发现 1,277 处问题。合并表格这件事,"合上"只是第一步,"每一条都有据可查"才算完。

作者所处行业与岗位:信息技术服务业 · 数据与效率工具工程师(日常工作涉及多版本数据集的比对、校验与增量备份,以及批处理流程的搭建与排障)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、痛点:合并后的表,谁也不敢用
  • 二、根因:pd.concat 只解决"拼起来",不解决"可信"
  • 三、实测对比:同一批数据,两种跑法
  • 四、可复制代码
  • 五、踩坑清单
  • 六、给 WorkBuddy 的提示词模板
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档