如何用Pandas对比两个DataFrame,提取DF1中更新行并忽略类型差异
解决DataFrame按ID匹配对比并提取差异行的方法
需求核心
- 以
id为唯一标识匹配两行,找出df1中与df2对应ID行值不同的记录,仅保留df1的这些行 - 忽略df2中df1没有的新行
- 处理数据类型差异(如int转float),统一转字符串进行对比
示例数据
DataFrame 1(昨日数据)
| id | name | last login | last order | total spent |
|---|---|---|---|---|
| 1 | Sean | 1/1/2023 | 1/1/2023 | 432 |
| 2 | John | 1/1/2023 | 1/1/2023 | 98 |
| 3 | Jim | 1/1/2023 | 1/1/2023 | 123 |
DataFrame 2(今日数据)
| id | name | last login | last order | total spent |
|---|---|---|---|---|
| 1 | Sean | 1/1/2023 | 1/1/2023 | 432 |
| 2 | John | 1/6/2022 | 1/6/2022 | 2 |
| 3 | Jim | 1/1/2023 | 1/1/2023 | 123 |
| 4 | Joe | 7/8/2022 | 7/8/2022 | 1503 |
实现代码
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({ 'id': [1, 2, 3], 'name': ['Sean', 'John', 'Jim'], 'last login': ['1/1/2023', '1/1/2023', '1/1/2023'], 'last order': ['1/1/2023', '1/1/2023', '1/1/2023'], 'total spent': [432, 98, 123] }) df2 = pd.DataFrame({ 'id': [1, 2, 3, 4], 'name': ['Sean', 'John', 'Jim', 'Joe'], 'last login': ['1/1/2023', '1/6/2022', '1/1/2023', '7/8/2022'], 'last order': ['1/1/2023', '1/6/2022', '1/1/2023', '7/8/2022'], 'total spent': [432, 2, 123, 1503] }) # 1. 按id合并两个DataFrame,只保留双方共有的行,用后缀区分新旧列 merged_df = pd.merge(df1, df2, on='id', suffixes=('_old', '_new'), how='inner') # 2. 生成差异掩码:任意一列转字符串后不相等即标记为差异行 diff_mask = False for col in df1.columns.drop('id'): diff_mask |= merged_df[f'{col}_old'].astype(str) != merged_df[f'{col}_new'].astype(str) # 3. 过滤出差异行,提取df1的原始记录 result = df1.loc[merged_df[diff_mask]['id'].index] print(result)
运行结果
| id | name | last login | last order | total spent |
|---|---|---|---|---|
| 2 | John | 1/1/2023 | 1/1/2023 | 98 |
关键说明
pd.merge(how='inner')自动过滤掉df2中的新行,只保留双方共有的id数据- 所有列转成字符串后对比,彻底避免数据类型差异(如int与float、日期格式不一致)导致的误判
- 通过逐列对比生成掩码,精准定位有变更的行,最终提取df1的对应记录
内容的提问来源于stack exchange,提问作者Empusas
相关产品推荐
相关产品推荐

