如何基于指定列移除存在于另一个pd.DataFrame中的行?
Pandas筛选DataFrame中未在另一DataFrame出现的行
你原来的代码c = a[a[matchcolumns] == b[matchcolumns]]没法实现需求,原因有两个:一是两个DataFrame行数不同时,列直接比较会产生大量NaN值,导致判断逻辑失效;二是代码逻辑是找a和b匹配列相等的行,而你要的是a中未在b出现的行,方向搞反了。
下面给两种靠谱的实现方法:
方法一:用merge+标记列筛选
这种方法逻辑清晰,适合大多数场景:
- 只保留b里的匹配列,和a做左连接,同时开启
indicator参数标记每行的来源 - 筛选出标记为
left_only的行,这些就是a独有的、没在b里出现的行 - 最后删掉标记列即可
import pandas as pd # 示例数据 a = pd.DataFrame({ 'color': ['red', 'blue', 'green'], 'value': [0.1, 0.2, 0.3], 'cost': [5.99, 6.99, 9.99] }) b = pd.DataFrame({ 'color': ['red'], 'value': [0.1], 'cost': [0.9] }) matchcolumns = ['color', 'value'] # 左连接并标记行来源 merged_df = a.merge(b[matchcolumns], on=matchcolumns, how='left', indicator=True) # 筛选a独有的行 c = merged_df[merged_df['_merge'] == 'left_only'].drop('_merge', axis=1) print(c)
方法二:转元组+isin取反
如果数据量不大,这种写法更简洁:
- 把b的匹配列转换成元组列表(因为isin不支持直接比较多列)
- 把a的匹配列也转成元组,用
isin判断是否存在于b的元组列表中,再用~取反 - 筛选出结果
import pandas as pd # 示例数据 a = pd.DataFrame({ 'color': ['red', 'blue', 'green'], 'value': [0.1, 0.2, 0.3], 'cost': [5.99, 6.99, 9.99] }) b = pd.DataFrame({ 'color': ['red'], 'value': [0.1], 'cost': [0.9] }) matchcolumns = ['color', 'value'] # 提取b中匹配列的元组集合 b_match_tuples = list(b[matchcolumns].itertuples(index=False, name=None)) # 筛选a中不在b里的行 c = a[~a[matchcolumns].itertuples(index=False, name=None).isin(b_match_tuples)] print(c)
两种方法运行后都会得到你期望的结果:
color value cost 1 blue 0.2 6.99 2 green 0.3 9.99
内容的提问来源于stack exchange,提问作者delete
相关产品推荐
相关产品推荐

