Pandas 比较两个数据帧并查找仅存在于一个数据帧中的条目的更好方法

Pandas better method to compare two dataframes and find entries that only exist in one

我有一个 DataFrame/spreadsheet,其中包含员工信息(姓名、工作地点)列以及总工作时数列。我的主要目标是找到存在于一个文件中但不存在于另一个文件中的员工。

DataFrame ORIGINAL:

 Name      Site    ....other columns
 Anne      A
 Bob       B
 Charlie   A

数据帧NEW:

 Name      Site    ....other columns
 Anne      A
 Bob       B
 Doug      B

DataFrame NEWORIGINAL 非常相似,但有一些差异,这些是我希望展示的细节

  1. Charlie/A 仅在 ORIGINAL
  2. Doug/B 仅在 NEW

我发现 ,它工作正常,但我需要执行两次以在一个 DataFrame 中查找记录而不是另一个,然后再次执行,反之亦然。

这是我的代码:

COLS = ['Name','Site'] # Columns to group by to find a 'unique' record

# Records in New, not in Original
df_right = ORIGINAL.merge(NEW.drop_duplicates(), on=COLS, how='right', indicator=True)
df_right = df_right[df_right._merge != 'both'] # Filter out records that exist in both.

# Records in Original, not in New
df_left = ORIGINAL.merge(NEW.drop_duplicates(), on=COLS, how='left', indicator=True)
df_left = df_left[df_left._merge != 'both']

df = pd.concat([df_left,df_right])
# df now contains Name/Site records that exist in one DataFrame but not the other

是否有更好的方法来执行此检查而不是执行两次并连接?

您实际上可以将数据帧转换为 Indexes,然后只需使用 isin 检查整行是否在另一个数据帧中:

cols = ['Name', 'Site']
originalI = pd.Index(ORIGINAL[cols])
newI = pd.Index(NEW[cols])

out = pd.concat([
    ORIGINAL[~originalI.isin(newI)].assign(from_df='ORIGINAL'),
    NEW[~newI.isin(originalI)].assign(from_df='NEW'),    
])

输出:

>>> out
      Name Site   from_df
2  Charlie    A  ORIGINAL
2     Doug    B       NEW

看起来像使用 'outer' 因为 how 是解决方案

z = pd.merge(ORIGINAL, NEW, on=cols, how = 'outer', indicator=True)
z = z[z._merge != 'both'] # Filter out records from both

输出看起来像这样(仅显示我关心的列之后)

  Name       Site   _merge
  Charlie    A     left_only
  Doug       B     right_only