如何从匹配 2 列的另一个数据框更新数据框的列值?

How to update column value of a data frame from another data frame matching 2 columns?

我有 2 个数据框,我想更新具有相同 2 列值的行的分数。

我该怎么做?

df 1:

DEP ID    |  Team ID |  Group    |   Score
001       |  002     |    A      |    50
001       |  004     |    A      |    70
002       |  002     |    A      |    50
002       |  007     |    A      |    90

df 2(一个部门的子集):

DEP ID    |  Team ID |  Group    |   Result
001       |  002     |    A      |    80
001       |  003     |    A      |    60
001       |  004     |    A      |    70

输出:所有具有相同 TeamID 和 Group 的列更新分数

DEP ID    |  Team ID |  Group    |   Score
001       |  002     |    A      |    80
001       |  004     |    A      |    70
002       |  002     |    A      |    80
002       |  007     |    A      |    90

我试过 pd merge left join 但我并没有真正得到预期的结果。

有什么建议吗?

这是一种方法:

df1 = df1.join(df2.drop(columns='DEP ID').set_index(['Team ID', 'Group']), on=['Team ID', 'Group'])
df1.loc[df1.Result.notna(), 'Score'] = df1.Result
df1 = df1.drop(columns='Result')

解释:

  • 修改 df2,使其索引为 Team ID, Group,其唯一列为 Result
  • 使用 join 将 df2 的新分数放入 df1
  • Result
  • 使用 loc 更新 Result 不为空的行的 Score 值(即更新的 Score 可用的行)
  • 删除 Result 列。

完整测试代码:

import pandas as pd
import numpy as np
df1 = pd.DataFrame({
'DEP ID':['001','001','002','002'],
'Team ID':['002','004','002','007'],
'Group':['A','A','A','A'],
'Score':[50,70,50,90]})
df2 = pd.DataFrame({
'DEP ID':['001','001','001'],
'Team ID':['002','003','004'],
'Group':['A','A','A'],
'Result':[80,60,70]})

print(df1)
print(df2)

df1 = df1.join(df2.drop(columns='DEP ID').set_index(['Team ID', 'Group']), on=['Team ID', 'Group'])
df1.loc[df1.Result.notna(), 'Score'] = df1.Result
df1 = df1.drop(columns='Result')
print(df1)

输出:

   index DEP ID Team ID Group  Score
0      0    001     002     A     80
1      1    001     004     A     70
2      2    002     002     A     80
3      3    002     007     A     90

更新:

如果 df2 中的 Result 列被命名为 Score,正如 OP 在评论中所要求的,那么代码可以稍微调整如下:

df1 = df1.join(df2.drop(columns='DEP ID').set_index(['Team ID', 'Group']), on=['Team ID', 'Group'], rsuffix='_NEW')
df1.loc[df1.Score_NEW.notna(), 'Score'] = df1.Score_NEW
df1 = df1.drop(columns='Score_NEW')