Pandas高效实现:基于首表日期筛选次表30天内重叠记录
高效筛选同人员30天内关联记录的实现方案
iterrows遍历效率极低,尤其是50万条数据的量级,完全不推荐。下面给你三种高效实现方式:
方案一:Pandas 合并+条件过滤(内存允许时优先)
先把日期转成datetime类型,按人员ID合并两张表,再筛选日期差在30天内的记录,最后去重避免重复条目。
import pandas as pd # 假设已读取数据到df1(Table1)、df2(Table2) df1['admission_date'] = pd.to_datetime(df1['admission_date']) df2['admission_date'] = pd.to_datetime(df2['admission_date']) # 按person_id合并两张表 merged_df = pd.merge(df2, df1, on='person_id', suffixes=('_t2', '_t1')) # 筛选日期差绝对值≤30天的记录 filtered_df = merged_df[abs(merged_df['admission_date_t2'] - merged_df['admission_date_t1']) <= pd.Timedelta(days=30)] # 提取Table2的字段并去重,得到Table3 table3 = filtered_df[['person_id', 'admission_date_t2', 'value_t2']].rename( columns={'admission_date_t2': 'admission_date', 'value_t2': 'value'} ).drop_duplicates()
方案二:Pandas merge_asof(有序数据下更高效)
如果两张表中每个人员的入院日期是有序的,用merge_asof可以按最近日期快速匹配,比普通合并效率更高,适合大数据量场景。
import pandas as pd # 转换日期类型,并按person_id和admission_date排序 df1['admission_date'] = pd.to_datetime(df1['admission_date']) df2['admission_date'] = pd.to_datetime(df2['admission_date']) df1_sorted = df1.sort_values(['person_id', 'admission_date']) df2_sorted = df2.sort_values(['person_id', 'admission_date']) # 按person_id分组,匹配前后30天内的记录 matched_df = pd.merge_asof( df2_sorted, df1_sorted, on='admission_date', by='person_id', tolerance=pd.Timedelta(days=30), direction='nearest' ).dropna(subset=['value_y']) # 剔除无匹配的记录 # 整理成Table3的结构 table3 = matched_df[['person_id', 'admission_date', 'value_x']].rename(columns={'value_x': 'value'})
方案三:SQL(超大数据量首选)
如果数据量突破百万级,直接在数据库用SQL处理是最优选择,不用把全量数据加载到内存,效率碾压Python遍历。以MySQL为例:
CREATE TABLE table3 AS SELECT DISTINCT t2.person_id, t2.admission_date, t2.value FROM table2 t2 INNER JOIN table1 t1 ON t2.person_id = t1.person_id WHERE ABS(DATEDIFF(t2.admission_date, t1.admission_date)) <= 30;
适用场景总结
- 中等数据量(百万以内)且内存充足:方案一或方案二,有序数据优先选方案二。
- 超大数据量(千万级及以上):直接用SQL在数据库中处理,避免内存瓶颈。
内容的提问来源于stack exchange,提问作者decabytes
相关产品推荐
相关产品推荐

