如何根据列从数据框中减去数据框?

时间:2021-04-07 12:10:26

标签: python pandas dataframe

我有以下数据框

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)

谁能指导我哪里做错了?

2 个答案:

答案 0 :(得分:3)

你想要的基本上是 Left join 减去 Inner Join 的结果。这看起来像是 merge 而不是 pd.concat 的典型案例。

df.mergeLeft 连接和 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)

代码中的问题

  1. 您连接了 df2 两次。 (尽管这并不重要,因为您随后会删除重复项。)
  2. 如果没有设置 pandas.DataFrame.drop_duplicatessubset 参数,默认情况下,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