首页 > 解决方案 > python pandas - 获取两个数据帧之间的匹配和不匹配记录

问题描述

我是在 python 中使用 pandas 的新手,而我对使用 python 有很好的了解。

我有两个数据框,我必须从中获取匹配的记录和不匹配的记录到新的数据框中。

例子 :

DF1:

ID Name Number    DOB     Salary
1  AAA  1234   12-05-1996 100000
2  BBB  1235   16-08-1997 200000
3  CCC  1236   24-04-1998 389999
4  DDD  1237   05-09-2000 450000

DF2:

ID Name Number    DOB     Salary
1  AAA  1234   12-05-1996 100000
2  BBB  1235   16-08-1997 200000
3  CCC  1236   24-04-1998 389999
4  DDD  1237   05-09-2000 540000

而且,这里的主键是 ID 和名称(实际上键的数量可能会有所不同),我需要得到

匹配_df:

ID Name Number    DOB     Salary
1  AAA  1234   12-05-1996 100000
2  BBB  1235   16-08-1997 200000
3  CCC  1236   24-04-1998 389999

不匹配_df:

ID Name Number    DOB     Salary
4  DDD  1237   05-09-2000 540000

我已经尝试了所有可能的方法,比如

pd.merge(df1, df2, left_on=[ID,Name],right_on=[ID,Name], how='inner')

这会产生两个数据帧中的所有唯一键。但这也会产生不匹配的记录。

但我得到了这个结果:

ID Name Number    DOB     Salary
1  AAA  1234   12-05-1996 100000
2  BBB  1235   16-08-1997 200000
3  CCC  1236   24-04-1998 389999
4  DDD  1237   05-09-2000 540000

其中第四条记录也被包括在内。

在这里,只有薪水 col 是变化的,但在实时,它可能是要比较的 cols 列表。

由此,我必须只获得匹配的记录到matched_df,不匹配的记录到mismatch_df。

请帮我做这件事。

注意:我的数据集可能是一个庞大的数据集(两个数据集中都有 1 亿条记录),所以请给我一个有效的方法来减少执行时间。

提前致谢。

标签: pythonpandascompare

解决方案


您的问题的简单答案是df1.where

注意:得到的带有 NaN 的单元格不满足条件,即它们在两个数据帧中不相等。具有实际价值的是两个数据帧中相等的那些

>>> df1.where(df1.Salary==df2.Salary)
          DoB   ID  Name    Salary
0  12-05-1996  1    AAA  100000.0
1  16-08-1997  2    BBB  200000.0
2  24-04-1998  3    CCC  389999.0
3         NaN  NaN  NaN       NaN

同时使用pd.merge:如果您只想合并没有列或索引级别的 df1 和 df1,那么它将默认为两个 DataFrame 中列的交集。

>>> pd.merge(df1, df2)
          DoB  ID Name  Salary
0  12-05-1996   1  AAA  100000
1  16-08-1997   2  BBB  200000
2  24-04-1998   3  CCC  389999

如果您希望加入列或索引级别,请使用on.

 >>> pd.merge(df1, df2, on="Salary")
        DoB_x  ID_x Name_x  Salary       DoB_y  ID_y Name_y
0  12-05-1996     1    AAA  100000  12-05-1996     1    AAA
1  16-08-1997     2    BBB  200000  16-08-1997     2    BBB
2  24-04-1998     3    CCC  389999  24-04-1998     3    CCC

对于不匹配df2 您可以选择isin(dict)方法:

>>> df2[~df2.isin(df1.to_dict('l')).all(1)]
          DoB  ID Name  Salary
3  05-09-2000   4  DDD  540000

Mabel 给出的另一种方式。

df2[~df2.isin(df1).all(axis=1)]

推荐阅读