You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:10:41