【问题标题】:Pandas: How to match / filter same key / id values (duplicates) from 2 different dataframes and replace values?Pandas:如何匹配/过滤来自 2 个不同数据帧的相同键/ID 值(重复项)并替换值?
【发布时间】:2021-11-10 19:20:25
【问题描述】:

我有 2 个不同大小的数据框。第一个数据框(df1)有 4 列,但其中两列与第二个数据框(df2)中的列同名,后者仅由 2 列组成。共同的列是['ID']['Department']

我想检查df2 中的ID 是否在df1 中。如果是这样,我想用df2['Department'] 值替换df1['Department'] 值。

例如,df1 看起来像这样:

ID      Department     Yrs Experience      Education
1234    Science        1                   Bachelors
2356    Art            3                   Bachelors
2456    Math           2                   Masters
4657    Science        4                   Masters

df2 看起来像这样:

ID      Department    
1098    P.E.
1234    Technology       
2356    History            
     

我想检查来自df2ID 是否在df1 中,如果是,请更新Department。输出应如下所示:

ID      Department     Yrs Experience      Education
1234    **Technology** 1                   Bachelors
2356    **History**    3                   Bachelors
2456    Math           2                   Masters
4657    Science        4                   Masters

df1 的预期更新以粗体显示

有没有有效的方法来做到这一点?

感谢您抽出宝贵时间阅读本文并提供帮助。

【问题讨论】:

  • 您能否编辑您的问题并将示例输入数据框df1df2 和预期输出放在那里?
  • @AndrejKesely 我刚刚编辑了它
  • 编辑问题以将df2 的样本数据改进为更真实的数据,其中匹配项的行索引不一定与df1 索引相同。

标签: python pandas dataframe duplicates dataset


【解决方案1】:

您可以使用df1ID 与将ID 上的ID 设置为索引并从df2 中取出Department 的列(这作为映射表)进行映射)。

然后,如果IDdf2不匹配,我们将Department的原始值从df1填入(不匹配时保留原始值):

df1['Department'] = (df1['ID'].map(df2.set_index('ID')['Department'])
                              .fillna(df1['Department'])
                    )

结果:

print(df1)

     ID  Department  Yrs Experience  Education
0  1234  Technology               1  Bachelors
1  2356     History               3  Bachelors
2  2456        Math               2    Masters
3  4657     Science               4    Masters

【讨论】:

    【解决方案2】:

    试试:

    df1["Department"].update(
        df1[["ID"]].merge(df2, on="ID", how="left")["Department"]
    )
    print(df1)
    

    打印:

         ID  Department  Yrs Experience  Education
    0  1234  Technology               1  Bachelors
    1  2356     History               3  Bachelors
    2  2456        Math               2    Masters
    3  4657     Science               4    Masters
    

    【讨论】:

    • 感谢您抽出宝贵时间帮助我。我尝试了您的解决方案,不幸的是,它没有更新 df1
    • @shorttriptomars 查看df1[["ID"]].merge(df2, on="ID", how="left") 的结果并检查df1df2 是否正确合并。
    • 我检查过,它们没有正确合并。我什至改变了“正确”的方式,但这也没有用
    • @shorttriptomars 确保ID 列的类型相同。如果是字符串,请检查其中的任何空格。
    • 对于两个ID 列,类型都是int64。虽然Department 的类型都是object,但我将两者都转换为str 只是为了确保。现在合并时,它在df1 中输出一个空白,而不是df2 中的值
    【解决方案3】:
    df_1 = pd.DataFrame(data={'ID':[1234, 2356, 2456, 4657], 'Department':['Science', 'Art', 'Math', 'Science']})
    df_2 = pd.DataFrame(data={'ID':[1234, 2356], 'Department':['Technology', 'History']})
    
    df_1.loc[df_1['ID'].isin(df_2['ID']), 'Department'] = df_2['Department']
    

    输出

         ID  Department
    0  1234  Technology
    1  2356     History
    2  2456        Math
    3  4657     Science
    

    【讨论】:

    • 感谢您抽出宝贵时间帮助我。我试过你的解决方案。它部分工作。它可以正确识别 df1 中 df2 的 ID,但不会替换 Department。相反,它输出空白。你知道如何解决这个问题吗?
    • 我在你的数据框上试过了,效果很好。
    • 检查输出。这就是我得到的。 span>
    • 实际数据是匹配ID行的行索引与2个dataframe不同。因此,您的解决方案直接从一个dataframe分配给另一个dataframe(并且这需要相同的匹配项索引)将产生不正确的结果。试试修改后的df2,在第一行再增加一行,然后你就会明白这是什么意思了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2017-12-23
    • 2015-10-23
    相关资源
    最近更新 更多