如何基于匹配条件在Pandas中从DataFrame移除指定行
从df2中移除与df1匹配行的实现方法
嘿,我来帮你搞定这个需求!看起来你需要从df2里剔除那些在df1中已经存在的完整行(也就是基于所有列完全匹配的记录),只保留df2独有的数据。下面给你几种实用的Pandas实现方案,附带代码和说明:
先准备测试数据
首先我们先把你给出的两个DataFrame创建出来,方便后续测试:
import pandas as pd # 构建df1 data1 = [ [2553,4,"192.168.1.9",2,"started"], [2556,4,"192.168.1.49",0,"started"], [2556,2,"192.168.1.25",25,"started"], [3056,8,"192.168.1.49",0,"started"] ] df1 = pd.DataFrame(data1, columns=["Process ID", "room no", "IP Address", "port", "status"]) # 构建df2 data2 = [ [2553,4,"192.168.1.9",2,"completed"], [2556,4,"192.168.1.49",0,"completed"], [2556,2,"192.168.1.25",25,"completed"], [2556,2,"192.168.1.46",25,"completed"], [3056,8,"192.168.1.49",0,"completed"] ] df2 = pd.DataFrame(data2, columns=["Process ID", "room no", "IP Address", "port", "status"])
方法一:使用merge + indicator标记
这种方法直观易懂,适合新手理解:
# 外连接合并两个DataFrame,添加_merge列标记行的来源 merged_df = df2.merge(df1, how="outer", indicator=True) # 筛选出仅在df2中存在的行,然后移除标记列 filtered_df = merged_df[merged_df["_merge"] == "left_only"].drop("_merge", axis=1)
原理:how="outer"会保留两个DataFrame的所有行,_merge列会显示当前行是来自left_only(仅df2有)、right_only(仅df1有)还是both(两个都有)。我们只保留left_only的行,就得到了df2中独有的数据。
方法二:使用isin + 元组匹配
这种方法代码更简洁,适合对Pandas操作熟悉的用户:
# 将df1的每一行转为元组,然后检查df2的行是否不在这个集合中 mask = ~df2.apply(tuple, axis=1).isin(df1.apply(tuple, axis=1)) filtered_df = df2[mask]
原理:apply(tuple, axis=1)把DataFrame的每一行转换成不可变的元组,然后用isin判断df2的行是否存在于df1的行集合中,~符号取反得到我们需要保留的行的掩码,最后筛选即可。
方法三:使用concat + drop_duplicates
如果你的数据量不大,这种方法也很方便:
# 合并df1和df2,然后按所有列去重,保留最后出现的行(即df2中的行) combined_df = pd.concat([df1, df2]) filtered_df = combined_df.drop_duplicates(subset=df1.columns, keep="last")
原理:把两个DataFrame拼接后,drop_duplicates会自动移除重复行,keep="last"指定保留最后出现的重复行——因为我们先拼了df1再拼df2,所以最后出现的就是df2里的行,这样就自动剔除了df1中已有的重复记录。
验证结果
不管用哪种方法,最终得到的filtered_df都会是:
| Process ID | room no | IP Address | port | status |
|---|---|---|---|---|
| 2556 | 2 | 192.168.1.46 | 25 | completed |
内容的提问来源于stack exchange,提问作者Jithesh Erancheri
相关产品推荐
相关产品推荐

