如何基于UniqueID对比获取df2中不存在的df1 DataFrame记录
嘿,这个需求太常见了!我来给你分享几个Pandas里实用的解决方案,都是我平时处理这类任务常用的方法,你可以根据自己的场景挑最合适的:
方法1:
isin() + 布尔索引(最直观) 这是最直接的写法,逻辑简单易懂,新手也能快速上手。
先模拟两个示例DataFrame方便你测试:
import pandas as pd # 示例df1 df1 = pd.DataFrame({ 'UniqueID': [1, 2, 3, 4, 5], 'Value': ['A', 'B', 'C', 'D', 'E'] }) # 示例df2 df2 = pd.DataFrame({ 'UniqueID': [2, 4, 6], 'Value': ['B', 'D', 'F'] })
然后筛选df1中UniqueID不在df2里的记录:
# 先获取df2的UniqueID集合,再用isin()判断,取反得到布尔索引 filtered_df = df1[~df1['UniqueID'].isin(df2['UniqueID'])]
解释一下:~是取反符号,isin()会返回一个布尔Series,标记df1的每个UniqueID是否在df2里,取反后就得到了不在df2里的行,再用这个索引筛选df1就行。
方法2:
merge() + indicator参数(适合需要确认匹配状态) 如果你不仅要筛选结果,还想看看每条记录的匹配情况(是只在df1,还是只在df2,或者两边都有),这个方法就很合适。
代码示例:
# 用outer join合并两个DataFrame,indicator=True会新增一列显示匹配状态 merged_df = df1.merge(df2, on='UniqueID', how='outer', indicator=True) # 筛选出只在df1里的记录 filtered_df = merged_df[merged_df['_merge'] == 'left_only'].drop(columns=['_merge', 'Value_y']) # 重命名列名还原成原来的样子(如果需要的话) filtered_df = filtered_df.rename(columns={'Value_x': 'Value'})
这里的_merge列会显示三种状态:left_only(只在df1)、right_only(只在df2)、both(两边都有),我们只需要筛选left_only的行就行,最后清理一下多余的列就搞定。
方法3:
query()方法(SQL风格,语法简洁) 如果你习惯SQL的写法,用query()会更顺手,代码更简洁:
# 把df2的UniqueID转成集合,然后用query筛选 filtered_df = df1.query('UniqueID not in @df2.UniqueID')
这里的@符号是用来引用Pandas外部的变量,把df2的UniqueID列传到query的表达式里,语法是不是和SQL的NOT IN很像?
小提醒
- 确保两个DataFrame的
UniqueID列数据类型一致,比如一个是整数一个是字符串的话,会匹配不上,必要时可以用astype()转换类型,比如df1['UniqueID'] = df1['UniqueID'].astype(str)。 - 如果df1里有重复的UniqueID,以上方法会保留所有重复行,如果你想去重,可以在筛选后加
drop_duplicates(subset='UniqueID')。
内容的提问来源于stack exchange,提问作者yanci
相关产品推荐
相关产品推荐

