Python中基于日期范围实现DataFrame多重复行的merge asof匹配问题
解决DataFrame多行日期匹配的问题
首先明确:merge_asof的设计逻辑是为左表每行匹配右表中符合条件的最近一行,天然做不到一对多的全匹配,得换思路处理。
方法一:先按公司合并,再过滤日期条件
这是最直接的实现方式,先把同一家公司的所有行组合出来,再筛掉不符合日期窗口的记录:
import pandas as pd # 先确保日期字段为datetime类型(若原始数据不是的话) df1['firm_date'] = pd.to_datetime(df1['firm_date']) df2['patent_filing_date'] = pd.to_datetime(df2['patent_filing_date']) # 按firm_id做内联接,得到同公司的所有行组合 df_combined = pd.merge(df1, df2, on='firm_id', how='inner') # 过滤日期条件:df2的专利申请日期处于df1对应日期的前5年窗口内 # 5年按1825天计算(包含闰年情况) date_window = pd.Timedelta(days=1825) df_final = df_combined[ (df_combined['patent_filing_date'] >= df_combined['firm_date'] - date_window) & (df_combined['patent_filing_date'] <= df_combined['firm_date']) ] # 可选:按需保留需要的字段 df_final = df_final[['firm_id', 'firm_date', 'patent_id', 'patent_filing_date']]
方法二:分组优化(大数据量场景)
如果你的DataFrame数据量很大,直接做全量合并会占用过多内存,可以按firm_id分组后逐个处理,再合并结果:
def process_firm_group(df1_sub, df2_sub): # 处理单家公司的匹配逻辑 combined = pd.merge(df1_sub, df2_sub, on='firm_id') date_window = pd.Timedelta(days=1825) return combined[ (combined['patent_filing_date'] >= combined['firm_date'] - date_window) & (combined['patent_filing_date'] <= combined['firm_date']) ] # 只保留两个表共有的公司ID,避免无效计算 common_firms = set(df1['firm_id'].unique()) & set(df2['firm_id'].unique()) # 逐个处理每家公司的数据 result_list = [] for firm in common_firms: df1_firm = df1[df1['firm_id'] == firm] df2_firm = df2[df2['firm_id'] == firm] matched_rows = process_firm_group(df1_firm, df2_firm) result_list.append(matched_rows) # 合并所有结果 df_final = pd.concat(result_list, ignore_index=True)
补充说明
- 日期窗口可按需调整:比如你若需要“df2日期在df1日期前5年到之后某段时间”,直接修改过滤条件即可。
- 原代码的局限性:
merge_asof的核心是匹配最近一行,不管有多少符合条件的记录,只会返回最接近的那一条,所以无法满足你要的多行匹配需求。
内容的提问来源于stack exchange,提问作者jayjunior
相关产品推荐
相关产品推荐

