You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Pandas中对两个非数值型DataFrame执行差集运算

如何计算两个同列DataFrame的差集(A - B)

你需要的是仅存在于df1(A)中、不存在于df2(B)中的行,也就是df1减去两者的交集。这里有几种实用的方法,结合你的示例代码来演示:

首先先补全示例数据,让演示更清晰:

import pandas as pd

# 初始化df1
df1 = pd.DataFrame(columns=['A','B','C'])
df1 = df1.append({'A': 'bmw','B':'three','C':'series'}, ignore_index=True)
df1 = df1.append({'A': 'merc','B':'S','C':'class'}, ignore_index=True)
df1 = df1.append({'A': 'Audi','B':'A','C':'4'}, ignore_index=True)  # 补全你未写完的行

# 初始化df2,包含和df1的交集行,以及新行
df2 = pd.DataFrame(columns=['A','B','C'])
df2 = df2.append({'A': 'bmw','B':'three','C':'series'}, ignore_index=True)
df2 = df2.append({'A': 'toyota','B':'Camry','C':'XLE'}, ignore_index=True)

方法1:使用merge的indicator参数(推荐)

这是最直观且处理边缘情况(比如缺失值)更友好的方法:

# 以左连接合并两个DataFrame,添加_merge列标记行的来源
merged_df = df1.merge(df2, on=['A', 'B', 'C'], how='left', indicator=True)

# 筛选出仅存在于df1的行,然后移除_merge列
df_diff = merged_df[merged_df['_merge'] == 'left_only'].drop('_merge', axis=1)

print(df_diff)

输出结果:

A  B     C
1   merc  S  class
2   Audi  A      4

原理:how='left'会保留df1的所有行,indicator=True会生成一个_merge列,值为left_only(仅在df1)、right_only(仅在df2)或both(同时存在于两者)。我们只需要筛选left_only的行即可。

方法2:利用集合的差集操作

如果你喜欢更简洁的集合运算,可以把每行转换成元组后计算差集:

# 将df1和df2的行转换为不含索引的元组集合
df1_rows = set(df1.itertuples(index=False, name=None))
df2_rows = set(df2.itertuples(index=False, name=None))

# 计算差集,再转换回DataFrame
diff_rows = df1_rows - df2_rows
df_diff = pd.DataFrame(diff_rows, columns=df1.columns)

print(df_diff)

输出结果和方法1一致(注意:集合是无序的,所以行的顺序可能和原df1不同,如果需要保持顺序,可以结合原df1的索引做二次筛选)。

⚠️ 注意:如果你的DataFrame中包含NaN值,这种方法可能会出错,因为NaN在集合中不会被视为相等(NaN != NaN),此时方法1会更可靠。

方法3:使用concat和drop_duplicates

这种方法通过标记来源后去重实现:

# 给两个DataFrame添加来源标记列
df1['source'] = 'df1'
df2['source'] = 'df2'

# 合并两个DataFrame
combined = pd.concat([df1, df2])

# 移除在两个DataFrame中都存在的行(即重复行)
unique_rows = combined.drop_duplicates(subset=['A', 'B', 'C'], keep=False)

# 筛选出仅来自df1的行,移除source列
df_diff = unique_rows[unique_rows['source'] == 'df1'].drop('source', axis=1)

print(df_diff)

这个方法同样能得到正确结果,但需要额外添加和移除标记列,相对前两种稍显繁琐。

内容的提问来源于stack exchange,提问作者Jeremy Hunts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:33:17