如何用Pandas按动态时间跨度生成含horizon列的透视表?
问题描述
给定如下结构的DataFrame(first_dt和dt为日期类型,且dt不早于first_dt):
first_dt dt val 2023-01-01 2023-01-02 1 2023-01-01 2023-01-02 1 2023-01-01 2023-01-03 1 ... 2023-01-02 2023-01-03 1 2023-01-02 2023-01-04 1
需要将其重塑为按first_dt分组,统计相对first_dt不同时间跨度(horizon)的val总和,目标结构如下:
first_dt horizon_1 horizon_2 horizon_3 2023-01-01 2 1 0 2023-01-02 1 1 0
最初尝试使用pandas.pivot_table(df, index='first_dt', columns='dt', values='val', aggfunc=np.sum),但当数据跨年度且仅需固定数量的horizon(如3、7天)时,该方法会生成大量冗余列,扩展性差。需要一种动态统计相对时间跨度的方法。
解决方案
步骤1:确保日期列类型正确
如果first_dt和dt是字符串类型,先转换为datetime格式:
import pandas as pd import numpy as np df['first_dt'] = pd.to_datetime(df['first_dt']) df['dt'] = pd.to_datetime(df['dt'])
步骤2:计算相对时间跨度(horizon)
计算dt与first_dt的天数差,生成对应的horizon标签:
# 天数差+1得到horizon序号(差1天对应horizon_1) df['horizon'] = (df['dt'] - df['first_dt']).dt.days + 1 # 转换为目标列名格式 df['horizon_col'] = 'horizon_' + df['horizon'].astype(str)
步骤3:过滤需要的horizon范围
假设只需要前3个horizon,过滤掉超出范围的行:
target_horizons = [f'horizon_{i}' for i in range(1, 4)] # 可按需修改范围,如1-7 df_filtered = df[df['horizon_col'].isin(target_horizons)]
步骤4:透视统计总和
使用pivot_table按first_dt和horizon_col聚合求和:
pivot_result = pd.pivot_table( df_filtered, index='first_dt', columns='horizon_col', values='val', aggfunc=np.sum, fill_value=0 )
步骤5:补全缺失列并排序
确保所有目标horizon列都存在,按顺序排列:
# 补全缺失的horizon列,填充0 pivot_result = pivot_result.reindex(columns=target_horizons, fill_value=0) # 可选:将first_dt从索引转为普通列 pivot_result = pivot_result.reset_index()
最终结果与目标结构一致,且只需修改target_horizons即可灵活调整统计的horizon数量,避免冗余列,大幅提升扩展性。
内容的提问来源于stack exchange,提问作者cdeterman
相关产品推荐
相关产品推荐

