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

如何用Pandas的groupby与reindex将事件型数据转换为时间序列?

将事件型薪资数据转换为规则时间序列的最优方案

我们需要把不规则间隔的事件型薪资数据转换为多时间序列,数据包含日期、员工姓名和变更后的薪资。目前已经通过循环+groupby/reindex/ffill实现了转换,但想找更简洁的标准方案。尝试直接调用df_events.groupby('employee')['salary'].reindex(time_series_index)时遇到错误:AttributeError: 'SeriesGroupBy' object has no attribute 'reindex',求最优实现方式。

原始事件数据

employee  salary
date                       
2000-01-01     anna    4500
2003-01-01      oli    5000
2010-01-01     anna    6500
2012-01-01     lena    5000
2013-01-01      oli    7000
2016-01-01     lena    6500
2017-01-09      joe    5000
2018-01-09    peter    5000
2019-01-09      joe    5500
2019-01-31     lena       0
2020-01-01     anna    8500
2020-01-09    peter    5500
2021-01-09      joe    6000
2022-02-28    peter       0

现有可行代码

time_series_index = pd.date_range(df_events.index.min(), df_events.index.max())
df_time_series = pd.DataFrame()
for name, group in df_events.groupby('employee'):
   time_series = group['salary'].reindex(time_series_index) 
   time_series = time_series.ffill().fillna(0)
   df_time_series[name] = time_series   
print(df_time_series)   

目标转换结果示例

anna     joe  lena     oli   peter
2000-01-01  4500.0     0.0   0.0     0.0     0.0
2000-01-02  4500.0     0.0   0.0     0.0     0.0
...            ...     ...   ...     ...     ...
2022-02-28  8500.0  6000.0   0.0  7000.0     0.0

最优实现方案

方案1:宽表重塑+全局重索引(推荐,性能最优)

通过unstack将长格式数据转为宽表,再一次性完成重索引和填充,完全避免循环:

# 生成完整时间索引
time_series_index = pd.date_range(df_events.index.min(), df_events.index.max())

df_time_series = (
    df_events['salary']
    .unstack('employee')  # 转成员工为列、日期为索引的宽表
    .reindex(time_series_index)  # 对齐到完整时间序列
    .ffill()  # 前向填充,延续上一次薪资值
    .fillna(0)  # 填充员工入职前的初始缺失值为0
)
print(df_time_series)

方案2:GroupBy+Apply(兼容原思路)

如果坚持用分组逻辑,可通过groupby.apply调用reindex,本质是封装了循环,但代码更简洁:

time_series_index = pd.date_range(df_events.index.min(), df_events.index.max())

df_time_series = (
    df_events.groupby('employee')['salary']
    .apply(lambda x: x.reindex(time_series_index).ffill().fillna(0))
    .unstack('employee')  # 转成宽表格式
)

内容的提问来源于stack exchange,提问作者barium

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 03:54:28