如何优化基于两列日期取交叉连接表唯一记录逻辑的速度与内存占用
优化方案
原方案性能差的核心原因是自定义apply函数会产生极高的逐组调用开销,同时逐组生成临时DataFrame也会占用大量内存。改用pandas内置向量化操作即可实现百倍级性能提升,150万行数据通常可在1分钟内跑完,内存占用仅为原方案的1/10不到。
实现代码
import pandas as pd import numpy as np # 1. 全量筛选符合日期条件的记录,避免逐组判断 valid_mask = df['P_DATE_ENCOUNTER'] > df['R_DATE_TESTED'] valid_df = df.loc[valid_mask, ['P_CLIENT_ID', 'P_DATE_ENCOUNTER', 'RECORD_ID', 'R_DATE_TESTED', 'R_RESULT']].copy() # 2. 分组内按测试日期降序排名,取每个分组最新的符合条件的记录 valid_df['rnk'] = valid_df.groupby(['P_CLIENT_ID', 'P_DATE_ENCOUNTER'])['R_DATE_TESTED']\ .rank(ascending=False, method='first') target_valid = valid_df[valid_df['rnk'] == 1].drop('rnk', axis=1) # 3. 关联全部分组,无符合条件记录的分组自动补空 all_groups = df[['P_CLIENT_ID', 'P_DATE_ENCOUNTER']].drop_duplicates() final_result = all_groups.merge(target_valid, on=['P_CLIENT_ID', 'P_DATE_ENCOUNTER'], how='left')
逻辑说明
- 和原方案逻辑完全一致:每个
(P_CLIENT_ID, P_DATE_ENCOUNTER)分组仅保留晚于就诊日期的最新一次测试记录,无符合条件记录的对应字段补空 - 所有操作均为pandas原生向量化实现,无自定义函数开销
- 若需进一步提速,可提前对
P_CLIENT_ID、P_DATE_ENCOUNTER、R_DATE_TESTED三个字段排序,替换rank操作为分组取首行,性能会再提升30%左右
内容的提问来源于stack exchange,提问作者Mazil_tov998
相关产品推荐
相关产品推荐

