如何更高效地对比两个Pandas DataFrame并识别修改行?
简洁对比目录结构DataFrame的差异(识别新增、删除、修改文件)
你有两个记录目录结构(含文件哈希)的Pandas DataFrame:
import pandas as pd dir_old = pd.DataFrame([ {"Filepath": "dir1/file1", "Hash": "hash1"}, {"Filepath": "dir1/file2", "Hash": "hash2"}, {"Filepath": "dir2/file3", "Hash": "hash3"}, ]) dir_new = pd.DataFrame([ # {"Filepath": "dir1/file1", "Hash": "hash1"}, # 已删除文件 {"Filepath": "dir1/file2", "Hash": "hash2"}, {"Filepath": "dir2/file3", "Hash": "hash5"}, # 修改的文件 {"Filepath": "dir1/file4", "Hash": "hash4"}, # 新增文件 ])
dir_new是修改后的目录结构,直接用pd.merge(..., how='outer', indicator=True)会把修改的文件拆成right_only和left_only两行,处理起来繁琐。下面是更简洁的差异对比方法:
方法:合并后直接标记变更类型
通过一次外合并,保留新旧哈希值,再通过自定义逻辑标记每个文件的状态:
- 执行外合并,保留两边的哈希并添加合并标记:
merged = pd.merge( dir_old, dir_new, on='Filepath', how='outer', suffixes=('_old', '_new'), indicator=True )
- 添加
ChangeType列标记文件状态:
merged['ChangeType'] = merged.apply( lambda row: 'modified' if row['_merge'] == 'both' and row['Hash_old'] != row['Hash_new'] else 'unchanged' if row['_merge'] == 'both' else 'deleted' if row['_merge'] == 'left_only' else 'added', axis=1 )
- 查看结果(可筛选出非不变更的行):
# 筛选所有有变化的文件 changes = merged[merged['ChangeType'] != 'unchanged'] print(changes[['Filepath', 'Hash_old', 'Hash_new', 'ChangeType']])
输出结果:
Filepath Hash_old Hash_new ChangeType 0 dir1/file1 hash1 NaN deleted 2 dir2/file3 hash3 hash5 modified 3 dir1/file4 NaN hash4 added
更简洁的写法(用numpy.where链式判断)
如果想进一步简化代码,同时提升大数据量下的处理效率,可以用numpy.where替代apply:
import numpy as np merged['ChangeType'] = np.where( merged['_merge'] == 'both', np.where(merged['Hash_old'] != merged['Hash_new'], 'modified', 'unchanged'), np.where(merged['_merge'] == 'left_only', 'deleted', 'added') )
内容的提问来源于stack exchange,提问作者asmaier
相关产品推荐
相关产品推荐

