Pandas:比较 2 个数据帧而不迭代

Sha*_*her 3 python dataframe pandas

考虑到我有如下所示的 2 个数据帧(DF1DF2),我需要将 DF2 与 DF1 进行比较,以便我可以识别 DF2 中与 DF1 中的列匹配的所有列的所有匹配、不同、缺失值(Col1、Col2 和 Col3对于具有相同 EID 值(A、B、C 和 D)的行。我不想迭代数据帧的每一行,因为它可能很耗时。注意:大约可以有 70 - 100 列。这只是我正在使用的示例数据框。

DF1

    EID Col1 Col2 Col3 Col4
0   A   a1   b1   c1   d1
1   B   a2   b2   c2   d2
2   C   None b3   c3   d3
3   D   a4   b4   c4   d4
4   G   a5   b5   c5   d5
Run Code Online (Sandbox Code Playgroud)

DF2

    EID Col1 Col2 Col3
0   A   a1   b1   c1
1   B   a2   b2   c9
2   C   a3   b3   c3
3   D   a4   b4   None
Run Code Online (Sandbox Code Playgroud)

Expected output dataframe

    EID Col1 Col2 Col3 New_Col
0   A   a1   b1   c1   Match
1   B   a2   b2   c2   Different
2   C   None b3   c3   Missing in DF1
3   D   a4   b4   c4   Missing in DF2
Run Code Online (Sandbox Code Playgroud)

小智 5

首先,您需要根据 df2 过滤 df1。

new_df = df1.loc[df1['EID'].isin(df2['EID']), df2.columns]

  EID  Col1 Col2 Col3
0   A    a1   b1   c1
1   B    a2   b2   c2
2   C  None   b3   c3
3   D    a4   b4   c4
Run Code Online (Sandbox Code Playgroud)

接下来,由于您有一个大数据框要比较,因此您可以将 和 更改new_dfdf2numpy 数组。

array1 = new_df.to_numpy()
array2 = df2.to_numpy()
Run Code Online (Sandbox Code Playgroud)

现在您可以使用逐行比较它np.where

new_df['New Col'] = np.where((array1 == array2).all(axis=1),'Match', 'Different')

  EID  Col1 Col2 Col3    New Col
0   A    a1   b1   c1      Match
1   B    a2   b2   c2  Different
2   C  None   b3   c3  Different
3   D    a4   b4   c4  Different
Run Code Online (Sandbox Code Playgroud)

最后,要转换具有值的行None,您可以使用df.locanddf.isnull

new_df.loc[new_df.isnull().any(axis=1), ['New Col']] = 'Missing in DF1'
new_df.loc[df2.isnull().any(axis=1), ['New Col']] = 'Missing in DF2'

  EID  Col1 Col2 Col3         New Col
0   A    a1   b1   c1           Match
1   B    a2   b2   c2       Different
2   C  None   b3   c3  Missing in DF1
3   D    a4   b4   c4  Missing in DF2
Run Code Online (Sandbox Code Playgroud)