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 NEW
与 ORIGINAL
非常相似,但有一些差异,这些是我希望展示的细节
- Charlie/A 仅在
ORIGINAL
- 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
是否有更好的方法来执行此检查而不是执行两次并连接?
您实际上可以将数据帧转换为 Index
es,然后只需使用 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
我有一个 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 NEW
与 ORIGINAL
非常相似,但有一些差异,这些是我希望展示的细节
- Charlie/A 仅在
ORIGINAL
- Doug/B 仅在
NEW
我发现
这是我的代码:
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
是否有更好的方法来执行此检查而不是执行两次并连接?
您实际上可以将数据帧转换为 Index
es,然后只需使用 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