Pandas 与重复的键合并 - 删除重复的行或阻止其创建



我有两个数据帧要合并,但我的键列包含重复项。数据帧如下所示:

Name,amount,id
John,500.25,GH10
Helen,1250.00,GH11
Adam,432.54,GH11
Sarah,567.12,GH12
Category,amount,id
Food,500.25,GH10
Travel,1250.00,GH11
Food,432.54,GH11

我正在执行它与外部联接的合并,以包括合并表中的所有内容:

merged_table = pd.merge(df1,df2,on="id",how='outer')

我的输出是:

Name,amount_x,id,category,amount_y
John,500.25,GH10,Food,500.25
Helen,1250.00,GH11,Travel,1250.00
Helen,1250.00,GH11,Food,432.54
Adam,432.54,GH11,Travel,1250.00
Adam,432.54,GH11,Food,432.54
Sarah,567.12,GH12

然而,我想要的输出是:

Name,amount_x,id,category,amount_y
John,500.25,GH10,Food,500.25
Helen,1250.00,GH11,Travel,1250.00
Adam,432.54,GH11,Food,432.54
Sarah,567.12,GH12

因此,这里发生的情况是,每个具有重复键的记录都与其他表上的每个记录匹配,因此输出有4行而不是2行,而中间的这两行(第2行和第3行(是不需要的。

因此,我想到的解决方案是:

  1. 防止以某种方式创建重复的行。在合并之前,我不能使用drop_duplicates((,因为这样我会排除一些带有doubled键的行。但是另一列Amount在两个表上应该有相同的2个值,但它们之间存在差异的可能性很小。

  2. 以与我相同的方式使用merge,但如果ID重复,则删除第2行和第3行,保留第1行和第4行,因为随着匹配的进行,df1中的第一行与df2中的第一行将连接,然后是df2中第二行,然后是df1中的第二行与df2中的第一行连接,然后与第二行连接,第1行与第4行才是正确的。

我想在这里使用.apply((并编写一些lambda函数,但我真的无法理解应该如何正确编写它。

我建议通过cumcount创建新的辅助列来计数id值,然后通过以下值合并:

df1['g'] = df1.groupby('id').cumcount()
df2['g'] = df2.groupby('id').cumcount()
merged_table = pd.merge(df1,df2,on=["id", 'g'],how='outer')
print (merged_table)
Name  amount_x    id  g Category  amount_y
0   John    500.25  GH10  0     Food    500.25
1  Helen   1250.00  GH11  0   Travel   1250.00
2   Adam    432.54  GH11  1     Food    432.54
3  Sarah    567.12  GH12  0      NaN       NaN

最后删除id:

merged_table = pd.merge(df1,df2,on=["id", 'g'],how='outer').drop('g', axis=1)
print (merged_table)
Name  amount_x    id Category  amount_y
0   John    500.25  GH10     Food    500.25
1  Helen   1250.00  GH11   Travel   1250.00
2   Adam    432.54  GH11     Food    432.54
3  Sarah    567.12  GH12      NaN       NaN 

详细信息

print (df1)
Name   amount    id  g
0   John   500.25  GH10  0
1  Helen  1250.00  GH11  0
2   Adam   432.54  GH11  1
3  Sarah   567.12  GH12  0
print (df2)
Category   amount    id  g
0     Food   500.25  GH10  0
1   Travel  1250.00  GH11  0
2     Food   432.54  GH11  1

在您的输出(merge之后(上,您可以在下面应用。同样,在一次拍摄中,我们可以做到,但我建议你想办法。给你提示。。。

>>> df.drop_duplicates('Name',keep='first')
Name  amount_x    id category amount_y
0   John    500.25  GH10     Food   500.25
1  Helen   1250.00  GH11   Travel     1250
3   Adam    432.54  GH11   Travel     1250
5  Sarah    567.12  GH12       

最新更新