Pandas如何基于不同日期周期合并日度与季度DataFrame
解决方案
前置准备
- 先将两个DataFrame的
Date列统一转换为pandas datetime类型,避免字符串格式的日期匹配出错 - 提前对季度数据按
Date列去重,保留每个起始日期对应的唯一生效季度值
推荐实现方法:使用pd.merge_asof
这是性能最优的实现方案,原理是按日度日期向前匹配最近的季度起始日期,刚好符合「季度值从起始日生效到下一季度前一天」的匹配规则。
必须确保两个DataFrame的Date列提前升序排序,否则merge_asof会返回错误结果
import pandas as pd # 构造示例日度数据 df_daily = pd.DataFrame({ 'Date': pd.date_range(start='2000-01-01', end='2000-04-01'), 'Daily_value': range(92) }) # 构造示例季度数据(自定义起始日) df_quarter = pd.DataFrame({ 'Date': pd.to_datetime(['2000-01-01', '2000-03-14', '2000-06-05']), 'Quarterly_value': [100, 200, 300] }) # 必须步骤:两个DataFrame按Date列升序排序 df_daily = df_daily.sort_values('Date').reset_index(drop=True) df_quarter = df_quarter.sort_values('Date').reset_index(drop=True) # 合并:按日度日期向前匹配最近的季度起始日 df_merged = pd.merge_asof( left=df_daily, right=df_quarter, on='Date', direction='backward' )
运行后2000-01-01到2000-03-13的日度记录会匹配到季度值100,2000-03-14到2000-06-04的日度记录会匹配到季度值200,完全符合需求。
可选小数据量方案:显式区间匹配
如果需要明确校验日期落在季度生效区间内,可以先给季度数据补充截止日期,再通过条件过滤匹配:
# 给季度数据添加生效截止日期:下一个季度起始日减1天,最后一个季度截止日设为日度数据最大日期 df_quarter['end_date'] = df_quarter['Date'].shift(-1) - pd.Timedelta(days=1) df_quarter['end_date'] = df_quarter['end_date'].fillna(df_daily['Date'].max()) # 交叉合并后过滤符合区间的匹配记录 df_merged = df_daily.assign(tmp_key=1).merge( df_quarter.assign(tmp_key=1), on='tmp_key' ).query('Date >= Date_y and Date <= end_date').drop(columns=['tmp_key', 'Date_y']).rename(columns={'Date_x': 'Date'})
该方案仅适合小数据量场景,数据量超过10万条时优先使用pd.merge_asof。
注意事项
- 若日度数据存在早于第一个季度起始日的记录,合并后
Quarterly_value会返回NaN,可根据需求选择提前过滤日度数据或用fillna()填充默认值。 - 若季度数据存在重复的起始日期,会按排序后的最后一条记录匹配,建议提前去重避免结果异常。
内容的提问来源于stack exchange,提问作者Kamo
相关产品推荐
相关产品推荐

