如何在Pandas中对两个DataFrame执行类似MINUS查询的操作?
实现DataFrame的MINUS操作(获取df1独有的行)
下面给你几种可行的实现方式,包括你问的merge方法,以及修复pandasql报错的方案:
方法一:用merge实现(适配你不确定共同列的场景)
因为MINUS是整行对比,直接用merge做左连接,自动匹配所有列名一致的列,标记出只在df1中存在的行即可:
import pandas as pd # 你的两个DataFrame示例 df_1 = pd.DataFrame({ 'Last': ['Thompson', 'Miller', 'Bryant', 'Jones'], 'First': ['Aaron', 'James', 'Samuel', 'Richard'], 'Role': ['Developer', 'Developer', 'Tester', 'Tester'], 'Salary': [72000, 68000, 54000, 56500] }) df_2 = pd.DataFrame({ 'Last': ['Thompson', 'Miller', 'Bryant', 'Nirmal'], 'First': ['Aaron', 'James', 'Samuel', 'Ojjaswi'], 'Role': ['Developer', 'Developer', 'Tester', 'Analyst'], 'Salary': [72000, 68000, 54000, 0] }) # 执行merge操作 result = df_1.merge(df_2, how='left', indicator=True) # 筛选仅存在于df1的行,移除标记列 result = result[result['_merge'] == 'left_only'].drop('_merge', axis=1) print(result)
输出结果就是df1独有的那一行:
Last First Role Salary 3 Jones Richard Tester 56500
方法二:修复pandasql的报错
你用pandasql报错是因为它底层用的SQLite不支持MINUS关键字,SQLite中对应的是EXCEPT,把SQL语句替换成下面的即可:
import pandasql as ps q1 = """SELECT * FROM df_1 EXCEPT SELECT * FROM df_2; """ print(ps.sqldf(q1, locals()))
执行后同样能得到正确结果。
方法三:用concat + 去重实现
把两个DataFrame合并后,删除重复行,只保留仅在df1中出现的行:
# 给两个DataFrame添加来源标记 df_1['source'] = 'df1' df_2['source'] = 'df2' # 合并后去重,keep=False删除所有重复出现的行 combined = pd.concat([df_1, df_2]).drop_duplicates(keep=False) # 筛选来源为df1的行,移除标记列 result = combined[combined['source'] == 'df1'].drop('source', axis=1) print(result)
方法四:行元组匹配法
把每行转成元组,直接判断是否存在于另一个DataFrame的行集合中:
# 把df2的所有行转成元组集合 df2_rows = set(df_2.apply(tuple, axis=1)) # 筛选df1中不在df2行集合里的行 result = df_1[~df_1.apply(tuple, axis=1).isin(df2_rows)] print(result)
内容的提问来源于stack exchange,提问作者ojjasvi nirmal
相关产品推荐
相关产品推荐

