2026-10-02 · 喵窝资源铺
八月收一次表、九月收一次、十月又收一次,按之前的方法合并成总表后,新问题来了:同一个人出现两三次,还各自带着不同时期的手机号、部门。直接 drop_duplicates() 会随机留一条——留了八月的旧号码就出事了。这篇给一个 「按日期排序后保留最新」 的方案:合并 → 按日期列排序 → 按关键列去重取最后一条。本文代码实跑验证,真实输出见下。
需要 pandas + openpyxl(pip install pandas openpyxl)。存为 dedup_keep_latest.py,运行 python dedup_keep_latest.py 数据文件夹 dedup.xlsx。关键列和日期列都可以从命令行换:
"""合并多个月份的 Excel 后按关键列去重,保留最新一条。
用法:python dedup_keep_latest.py [输入目录] [输出xlsx] [关键列] [日期列]"""
import sys, glob, os
import pandas as pd
src = sys.argv[1] if len(sys.argv) > 1 else "."
out = sys.argv[2] if len(sys.argv) > 2 else "dedup.xlsx"
KEY = sys.argv[3] if len(sys.argv) > 3 else "手机号"
DATE = sys.argv[4] if len(sys.argv) > 4 else "登记日期"
frames = []
for f in sorted(glob.glob(os.path.join(src, "*.xlsx"))):
if os.path.basename(f) == os.path.basename(out): # 防止把上次的输出又吃进来
continue
frames.append(pd.read_excel(f))
merged = pd.concat(frames, ignore_index=True)
n0 = len(merged)
merged[DATE] = pd.to_datetime(merged[DATE]) # 日期列转真日期,字符串排序才不出"2026-9-5"排错
merged = (merged.sort_values(DATE)
.drop_duplicates(subset=[KEY], keep="last") # 排序后留最后一条=最新
.sort_values(DATE, kind="stable"))
merged.to_excel(out, index=False)
print(f"{len(frames)} 个文件共 {n0} 行, 按[{KEY}]去重保留[{DATE}]最新 -> {len(merged)} 行 -> {out}")
print(merged.to_string(index=False))
我造了 3 个月份的文件共 7 行:张三出现 3 次(八月旧号码→九月新号码→十月最新),李四出现 2 次(十月还改了个名字备注「改号?」),王五、小元各 1 次。跑一遍:
3 个文件共 7 行, 按[手机号]去重保留[登记日期]最新 -> 4 行 -> dedup.xlsx
手机号 姓名 登记日期
13711112222 王五 2026-09-20
13987654321 李四(改号?) 2026-09-28
13812345678 张三(最新) 2026-10-01
13699998888 小元 2026-10-02
核对:张三只留下十月的「张三(最新)」,八月九月两条旧记录被正确丢弃;李四留九月 28 日的;只出现一次的王五、小元原样保留。幂等验证:输入不动再跑一遍,还是 7 行进 4 行出、结果完全一致——脚本不做任何破坏性修改(原文件不动),所以重复运行安全。
pd.to_datetime() 转一遍再排,一步都不能省。if basename == out: continue 就是为此写的。这个方案默认「同一关键列 = 同一个人」。如果手机号可能换号、或者要「手机号相同就算重复」之外的模糊匹配(同名不同号),逻辑要另写一层,可以直接找我们代写(见下)。
相关阅读:列名不统一的 Excel 合并 | 多 CSV 合并去重 | Excel 数据清洗常用脚本 | 两份流水账自动对账