# pandas求两个DataFrame之间的行的差集

import pandas as pd

# 假设我们有两个DataFrame
df1 = pd.DataFrame({
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3']
})

df2 = pd.DataFrame({
'A': ['A0', 'A2', 'A4'],
'B': ['B0', 'B2', 'B4'],
'C': ['C0', 'C2', 'C4']
})

# 首先通过outer join找出所有记录
merged = pd.merge(df1, df2, how='outer', indicator=True, on=list(df1.columns))

# 然后根据"_merge"列找出只在df1或df2出现的行
df_left_only = merged[merged['_merge'] == 'left_only']
df_right_only = merged[merged['_merge'] == 'right_only']

# 这里df_left_only就是df1相对于df2的差集，df_right_only是df2相对于df1的差集
print("df1相对于df2的差集：")
print(df_left_only)

print("\ndf2相对于df1的差集：")
print(df_right_only)


df1_unique_rows = df1.apply(lambda row: tuple(row), axis=1).drop_duplicates()
df2_unique_rows = df2.apply(lambda row: tuple(row), axis=1).drop_duplicates()

df1_diff_df2 = df1_unique_rows[~df1_unique_rows.isin(df2_unique_rows)]
df2_diff_df1 = df2_unique_rows[~df2_unique_rows.isin(df1_unique_rows)]

print("df1相对于df2的差集（按所有列值均不同定义）：")
print(df1.iloc[df1_diff_df2.index])

print("\ndf2相对于df1的差集（按所有列值均不同定义）：")
print(df2.iloc[df2_diff_df1.index])


### 具体例子

import pandas as pd

# DataFrame 1
df1 = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Age': [25, 30, 35, 40]
})

# DataFrame 2
df2 = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Eve', 'Frank'],
'Age': [25, 30, 40, 45]
})


# 首先确保两个DataFrame有相同的列名和数据类型
if set(df1.columns) == set(df2.columns) and df1.dtypes.equals(df2.dtypes):
# 使用merge方法配合indicator参数找差集
merged = pd.merge(df1, df2, how='outer', indicator=True, on=list(df1.columns))

df1_diff_df2 = merged[merged['_merge'] == 'left_only']
df2_diff_df1 = merged[merged['_merge'] == 'right_only']

print("df1相对于df2的差集：")
print(df1_diff_df2)

print("\n df2相对于df1的差集：")
print(df2_diff_df1)
else:
print("两个DataFrame的列名或数据类型不匹配，无法直接计算差集。")

# 输出：
# df1相对于df2的差集：
#     Name  Age     _merge
# 2  Charlie  35  left_only
# 3    David  40  left_only

# df2相对于df1的差集：
#     Name  Age     _merge
# 2     Eve  40  right_only
# 3   Frank  45  right_only


• 8
点赞
• 10
收藏
觉得还不错? 一键收藏
• 0
评论
12-04 2260
06-12 1万+
03-21 776
04-14 2121
09-29 390
02-08 2900
07-16 5659
07-12 167
02-02 156

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。