Pandas合并月度/日度时间序列DataFrame并应用滞后值
问题根因
之前的代码无法生效核心是三个逻辑错误:
- 对月度频率的df1直接调用
shift(-30)是按行号偏移,不是按时间维度偏移30天,月度数据单月仅1行,偏移30行后所有值都会变成空值 - 普通
merge要求关联键值完全相等,df1的Date是月度粒度(如2016-03)、df2的Date是日度粒度(如2016-03-21),格式不统一无法直接匹配 merge_asof的传参顺序错误:该函数以左表为基准匹配右表,要以日度粒度对齐需要把df2放在左表位置,且必须先将两个表的Date列统一转换为datetime类型,否则时间匹配逻辑无法正常运行
实现代码
前置处理
首先统一两个表的时间格式:
import pandas as pd df1['Date'] = pd.to_datetime(df1['Date']) df2['Date'] = pd.to_datetime(df2['Date'])
方案1:全列统一-30天滞后
直接通过merge_asof的时间匹配参数实现,不需要提前做shift操作,匹配逻辑完全按真实时间差计算:
out = pd.merge_asof( df2.sort_values('Date'), # merge_asof要求关联键必须按升序排列 df1.sort_values('Date'), on='Date', direction='forward', # 匹配晚于当前日期的最近值,对应lag=-30的前置效果 tolerance=pd.Timedelta(days=30) # 匹配范围不超过30天,避免跨多月匹配 )
运行结果和示例预期完全一致:2016-03-21至2016-03-31的日度数据会匹配2016-04的月度值,2016-04-01起30天内的日度数据会匹配2016-05的月度值。
方案2:多列独立配置不同滞后期
针对需要给不同列设置不同滞后期的场景,逐列做时间偏移后匹配,避免行号偏移导致的错位问题:
# 按业务需求配置每列的滞后天数:负数为向前取未来N天的数据,正数为向后取历史N天的数据 lag_config = { 'Col1': -30, 'Col 2': -30, 'Col 3': -7, # 示例:Col3单独设置-7天滞后 'Col 4': 0 # 示例:Col4不做滞后,直接按日期匹配 } out = df2.sort_values('Date').copy() for col, lag_days in lag_config.items(): # 为当前列构造匹配用的时间偏移键 temp_col_df = df1[['Date', col]].copy() temp_col_df['match_key'] = temp_col_df['Date'] - pd.Timedelta(days=lag_days) # 按偏移后的时间键做最近匹配 match_res = pd.merge_asof( out[['Date']], temp_col_df[['match_key', col]], left_on='Date', right_on='match_key', direction='forward' ) out[col] = match_res[col].values
该方案所有偏移计算基于真实日历时间,不受两个数据集的频率差、行数差影响,每列的匹配逻辑完全独立,调整滞后期只需要修改配置字典即可,不需要改动核心代码。
内容的提问来源于stack exchange,提问作者kiwi_kimchi
相关产品推荐
相关产品推荐

