表格双表核对 (ym-table-diff-audit)
按匹配键把两份表格逐行比对,给出未匹配、重复键、数值差异,并让结果可复算——普通对话容易漏掉重复键、把空值当 0、用等号比浮点,这些坑这里一次性堵住。
何时使用
- 用户说「对一下这两份表」「看看差异」「两份数据哪里不一样」「核对报表」「数据比对」「table diff」时
- 用户贴了两份 CSV / 导出报表,问「哪里对不上」「有没有漏数」时
- 财务、运营、数据岗做月底对账、跨系统数据抽查时
运行前提
- 依赖:Python 标准库
csv,无任何第三方包。系统 Python 即可运行,无需pip install。 - 输入格式:CSV。xlsx 用户请先「另存为 CSV」再跑;本技能不解析 xlsx(不引入 openpyxl,避免装包)。
- 全程只读:不修改、不覆盖、不新建原始文件,不保留数据副本。
- 编码:脚本自动尝试 UTF-8(BOM) / UTF-8 / GBK。
输入契约
| 项 | 必需 | 说明 |
|---|---|---|
| A 表、B 表 | 必需 | 两份 CSV;可给文件路径,也可由用户直接粘贴内容(粘贴时先落成临时 CSV) |
| 匹配键列名 | 必需 | 可多列组合,如 id 或 order_id,sku |
| 比对数值列 | 可选 | 如 amount,qty;不填则比对除键外所有列 |
| 数值容差 | 可选 | 默认 0.01,用户可改 |
| 忽略大小写 / 去空格 | 可选 | 默认去前后空格;--ignore-case 可开启键与字符串的大小写忽略 |
缺失处理:
- 缺匹配键 → 先列出两表共有列,请用户指定,不猜测。
- 两表列名不同(如
user_idvsuid)→ 请用户确认对应关系,并在报告写映射对照,不隐式改写。 - 容差未给 → 用默认
0.01,并在报告概览里写明。
执行步骤
-
确认输入 — 拿到两表与匹配键。若给的是路径,先
ls/读头几行确认能解析;若是粘贴内容,落成临时 CSV 再处理。 -
跑脚本比对 — 命令行形如:
python scripts/diff_tables.py A.csv B.csv --key id --cols amount,qty --tolerance 0.01复合键:
--key order_id,sku;要忽略大小写加--ignore-case;不要去空格加--no-strip。 -
核对概览 — 报告首段给出两表行数、列名、键、比对列、容差,以及「仅 A 有 / 仅 B 有 / 一致 / 差异 / 重复键」计数。确认计数与预期量级相符,再往下看。
-
分类看差异(按
references/diff-rules.md的判定规则复核):- 仅 A 有 / 仅 B 有:判断是漏数还是新增。
- 数值差异:检查差值与容差,确认不是浮点误差。
- 重复键:这一节必须存在且未静默去重;提醒用户先确认归属。
-
三态空值复核 — 报告里
(空字符串)、(缺失)、0必须分别标注。发现任何把空值当 0 的写法,立即纠正。 -
输出可复算说明 — 报告末尾必须带完整复现命令、参与键数、容差、忽略规则。没有这段,结论无法被审计。
-
硬性约束:只读取、不修改原文件;样本超过用户设定阈值时先展示前 N 条并说明总数,不一次倾倒全量;敏感列只在报告展示键与差异,不全文回显。
输出格式
Markdown 报告,套用 templates/diff-report-template.md,固定五段:
## 核对概览
## 仅 A 有(在 B 中找不到匹配键)
## 仅 B 有(在 A 中找不到匹配键)
## 数值 / 内容差异
## 需你确认的(重复键 / 空值 / 列名映射)
## 可复算说明
若用户要差异明细落地,可把「数值 / 内容差异」表导出为 CSV 写到用户指定目录(仍是新建文件,不碰原表)。
能力边界
- 不修复数据、不回写原表、不做跨表复杂 JOIN。
- 不解析 xlsx(请另存为 CSV);不声称具备审计或合规认证效力。
- 不联网、不上传表格内容;不对原文件做任何写操作。
- 重复键无法自动归属,必须交回用户确认。
常见坑
- 把空字符串当 0 — 现象:对账时「金额空」被算成「金额 0」,漏掉一笔差异。原因:看到单元格空就默认填 0。规避:严格三态区分,空字符串/缺失与 0 不同,报告里分开标注。
- 重复键静默取第一条 — 现象:主键重复的导出只比了其中一行,另一行差异被吞掉。原因:用 dict 建索引时后写覆盖先写。规避:重复键单独成节,不参与 1:1 比对,进「需你确认的」。
- 用等号比浮点 — 现象:
100.00和100.0被判不同,100.0000001被判不同。原因:直接字符串/浮点相等。规避:数值用容差abs(B-A) <= 容差判定,默认 0.01。 - 列名不同就硬比 — 现象:
user_id对uid全判「仅 A 有 / 仅 B 有」。原因:没确认映射。规避:列名不一致先请用户确认对应关系,写进报告。 - 缺匹配键就猜 — 现象:模型自选一列当主键,结论对但键是错的。原因:用户没给键时代为假设。规避:列出共有列请用户指定,绝不猜测。
- 结果不可复算 — 现象:报告只有差异清单,别人无法验证。原因:没留命令与参数。规避:末尾固定附「复现命令 + 容差 + 键数」,这是审计可信的依据。
验收用例
- 正常:两份各若干行 CSV,主键
id→ 差异分类齐全,数字带差值与容差,可复算。 - 边界 1:A 表主键有重复 → 重复键单独成节,不静默去重。
- 边界 2:数值列含空值 → 明确区分空值与 0,不填 0。
- 失败:用户没给匹配键 → 列出共有列请用户指定,不猜测。
目录说明
scripts/diff_tables.py— 双表核对主脚本(Python 标准库,只读不写)references/diff-rules.md— 三态空值、重复键、容差、可复算等判定规则templates/diff-report-template.md— 报告输出模板
微信扫一扫