如何用Pandas对比新旧DataFrame,捕获新增行与日期变更并生成告警?
优化方案:捕获DataFrame的新增行与日期变更并生成告警
核心思路
原代码的问题在于误用笛卡尔积(cross join)和去重逻辑,无法基于行的唯一标识做匹配,自然无法捕获新增数据。我们需要以Client、Opp、Description作为行的唯一主键,通过全外连接合并两个DataFrame,以此区分新增行、日期变更行,同时保留旧日期信息。
步骤与代码实现
1. 预处理:统一日期格式(可选但推荐)
将Date列转为datetime类型,避免字符串格式差异导致的比较错误:
import pandas as pd import numpy as np # 转换日期格式(适配dd/mm/yyyy的输入格式) Status["Date"] = pd.to_datetime(Status["Date"], dayfirst=True) Default["Date"] = pd.to_datetime(Default["Date"], dayfirst=True)
2. 基于主键全外连接两个DataFrame
用行的唯一标识主键合并表,确保所有新增、变更、删除的行都被保留:
# 定义行的唯一主键列 key_cols = ["Client", "Opp", "Description"] # 全外连接,区分新/旧数据的字段 merged = pd.merge( Status, Default, on=key_cols, how="outer", suffixes=("_new", "_old") )
3. 筛选并标记告警类型
筛选出需要告警的行,并明确标记类型:
# 标记告警类型:新增行/日期变更/无变更 merged["Alert_Type"] = np.where( merged["Date_old"].isna(), "新增行", np.where(merged["Date_new"] != merged["Date_old"], "日期变更", "无变更") ) # 仅保留需要告警的行 alerts = merged[merged["Alert_Type"] != "无变更"].copy()
4. 整理告警信息(包含旧日期)
统一旧日期的显示格式,整理输出所需字段:
# 格式化日期显示,新增行的旧日期填充为"无" alerts["旧日期"] = alerts["Date_old"].dt.strftime("%d/%m/%Y").fillna("无") alerts["新日期"] = alerts["Date_new"].dt.strftime("%d/%m/%Y") # 输出精简的告警内容 final_alerts = alerts[[ "Client", "Opp", "Description", "Alert_Type", "旧日期", "新日期" ]]
效果说明
- 新增行:标记为「新增行」,旧日期显示为「无」
- 日期变更行:标记为「日期变更」,同时显示被替换的旧日期和新日期
- 无变更的行:会被自动过滤,不生成告警
内容的提问来源于stack exchange,提问作者tatankadrums
相关产品推荐
相关产品推荐

