如何正确筛选df2中指定多列值组合存在于df1中的行?
如何过滤pandas DataFrame中指定组合列存在于另一个DataFrame的行?
你遇到的问题其实是想要实现半连接(Semi-Join):只保留df2中那些TG_ID、ORG_NO、DATA_DATE组合同时存在于df1的行,而且不需要把df1的其他列合并进来。
为什么之前的方法不行?
- 用
merge(df1, on=["TG_ID", "ORG_NO", "DATA_DATE"])的时候,默认是内连接(Inner Join),会把两个DataFrame的所有列都合并到结果里,所以你会得到很多额外的列(比如df1里的TG_CAP、I1-I96等);如果df1中存在重复的键组合,还会导致结果行数比df2多。 - 用
join报错是因为join默认基于索引匹配,但你没有把df1的索引设置为这三列的复合索引,导致left_on的列数和右边索引的层数不匹配,所以抛出了len(left_on) must equal the number of levels in the index of "right"的错误。
正确的实现方法
这里有两种简洁高效的方式:
方法1:用merge做半连接(推荐)
只提取df1中需要匹配的三列并去重,然后和df2做内连接,这样只会保留df2的列,且只保留符合条件的行:
# 先提取df1中唯一的键组合 df1_unique_keys = df1[["TG_ID", "ORG_NO", "DATA_DATE"]].drop_duplicates() # 和df2做内连接,只保留df2的行中键组合存在于df1的部分 df2_filtered = df2.merge(df1_unique_keys, on=["TG_ID", "ORG_NO", "DATA_DATE"], how="inner")
方法2:用isin结合元组匹配
把两个DataFrame的三列转换为元组的形式,然后用isin判断:
# 把df1的键组合转为元组列表 df1_key_tuples = df1[["TG_ID", "ORG_NO", "DATA_DATE"]].apply(tuple, axis=1).tolist() # 过滤df2中键组合在df1里的行 df2_filtered = df2[df2[["TG_ID", "ORG_NO", "DATA_DATE"]].apply(tuple, axis=1).isin(df1_key_tuples)]
这两种方法都能实现你的需求:比如df2的第27行因为ORG_NO=134010901不在df1的键组合里会被过滤,第28行的组合存在则会被保留。
内容的提问来源于stack exchange,提问作者user9875189
相关产品推荐
相关产品推荐

