我有以下数据框
df1 = pd.DataFrame({
'contact_id': [1,3,4,5,-1],
'subscription_id': ['AAA', 'ccc', 'ddd', 'eee', 'fff']
});
print(df1)
contact_id subscription_id
0 1 AAA
1 3 ccc
2 4 ddd
3 5 eee
4 -1 fff
第二个数据框
df2 = pd.DataFrame({
'contact_id': [1,2,-1],
'subscription_id': ['AAA', 'bbb', 'fff'],
'extra': ['we', 'kl', 'op']
});
print(df2)
contact_id subscription_id extra
0 1 AAA we
1 2 bbb kl
2 -1 fff op
预期产出
contact_id subscription_id extra
1 3 ccc NaN
2 4 ddd NaN
3 5 eee NaN
我的代码
import pandas as pd
df1 = pd.DataFrame({
'contact_id': [1,3,4,5,-1],
'subscription_id': ['AAA', 'ccc', 'ddd', 'eee', 'fff']
});
print(df1)
df2 = pd.DataFrame({
'contact_id': [1,2,-1],
'subscription_id': ['AAA', 'bbb', 'fff'],
'extra': ['we', 'kl', 'op']
});
print(df2)
sub = pd.concat([df1, df2, df2]).drop_duplicates(keep=False)
print(sub)
谁能指导我哪里做错了?
答案 0 :(得分:3)
你想要的基本上是 Left join
减去 Inner Join
的结果。这看起来像是 merge
而不是 pd.concat
的典型案例。
将 df.merge
与 Left
连接和 indicator
列用作 True
。仅通过选择 df1
来选择出现在 left_only
中的行:
In [1586]: df1.merge(df2, how='left', indicator=True).query('_merge == "left_only"').drop('_merge', 1)
Out[1586]:
contact_id subscription_id extra
1 3 ccc NaN
2 4 ddd NaN
3 5 eee NaN
答案 1 :(得分:0)
sub = pd.concat([df1, df2, df2]).drop_duplicates(keep=False)
代码中的问题
df2
两次。 (尽管这并不重要,因为您随后会删除重复项。)pandas.DataFrame.drop_duplicates
的 subset
参数,默认情况下,pandas 将使用所有列来识别重复项。由于 extra
列是不必要的,您可以使用布尔索引
df1 = df1.loc[~((df1['contact_id'].isin(df2['contact_id']))&(df1['subscription_id'].isin(df2['subscription_id'])))]
# print(df1)
contact_id subscription_id
1 3 ccc
2 4 ddd
3 5 eee