可以在pandas中执行左连接,只选择右边的第一个匹配吗?

Qua*_*ant 12 python left-join pandas

可以在pandas中执行左连接,只选择右边的第一个匹配吗?例:

left            = pd.DataFrame()
left['age']     = [11, 12]
right           = pd.DataFrame()
right['age']    = [10, 11, 11]
right['salary'] = [ 100, 150, 200 ]
left.merge( right, how='left', on='age' )
Run Code Online (Sandbox Code Playgroud)

返回

   age  salary
0   11     150
1   11     200
2   12     NaN
Run Code Online (Sandbox Code Playgroud)

但我想通过仅仅进行第一场比赛来保留左边的行数.那是:

   age  salary
0   11     150
2   12     NaN
Run Code Online (Sandbox Code Playgroud)

所以我一直在使用

left.merge( right.drop_duplicates(['age']), how='left', on='age')
Run Code Online (Sandbox Code Playgroud)

但我相信这是正确的完整副本.它闻起来很有趣.

有更优雅的方式吗?

小智 6

是的,您可以使用 groupby 删除重复的行。做你所做的一切来定义左和右。现在,我在你的最后一行定义了一个新的数据框:

left2=left.merge( right, how='left', on='age' )
df= left2.groupby(['age'])['salary'].first().reset_index()
df
Run Code Online (Sandbox Code Playgroud)

起初我使用了一个 .min(),它会给你每个年龄的最低工资,例如:

df= left2.groupby(['age'])['salary'].min().reset_index()
Run Code Online (Sandbox Code Playgroud)

但是您特别询问了第一场比赛。为此,您可以使用 .first() 选项。注意:最后的 .reset_index() 只是将 groupby 的输出重新格式化为数据帧。

  • 这仅在关键“年龄”在 *left* 中是唯一的假设下才有效,因此它在此示例中有效,但不能作为进行左合并的一般方法,这应该使 *left* 数据​​框完整 (2认同)
  • @576i 我同意。另外 `left2.groupby(['age'])['salary'].first().reset_index()` 只是一种更复杂的方式来执行 `left2.drop_duplicates(['age'])` OP 提出。 (2认同)