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

Pandas按id分组补全时间步后如何将同组数据转为单行?

Pandas 固定时间步缺失补全+长表转宽表实现

问题说明

给定包含id、val、date三列的DataFrame,每个id对应单日5个固定时间步(6:00、6:15、6:30、6:45、7:00),部分id存在时间步缺失,需要将缺失位置填充为NaN,最终输出每个id占一行的宽表,每个时间步的val单独成列。

测试数据构造代码如下:

import pandas as pd
df = pd.DataFrame()
df['id'] =   [1, 1, 1, 1, 1, 2, 2, 2,3, 3]
df['val'] = [11, 10, 12, 3, 4, 5, 125, 45,31, -2]
df['date'] = ['2019-03-31 06:00:00','2019-03-31 06:15:00', '2019-03-31 06:30:00', '2019-03-31 06:45:00', '2019-03-31 07:00:00', '2019-03-31 06:00:00', '2019-03-31 06:30:00',
              '2019-03-31 06:45:00', '2019-03-31 06:00:00', '2019-03-31 06:15:00']

测试数据特征:

  • id=1 包含全部5个时间步
  • id=2 缺失6:15、7:00两个时间步
  • id=3 缺失6:30、6:45、7:00三个时间步

实现代码

方法1:通用版(适配多日期场景,自动补全全量时间步)

先为每个id补全所有固定时间步,缺失值自动填充NaN后再转宽表,逻辑稳定:
注意:如果数据包含多个不同日期,生成多重索引时把日期维度也加入from_product的参数列表即可适配。

# 1. 格式预处理
df['date'] = pd.to_datetime(df['date'])
df['time_slot'] = df['date'].dt.strftime('%H:%M')  # 提取时分作为时间步标识
fixed_time_slots = ['06:00', '06:15', '06:30', '06:45', '07:00']  # 固定时间步列表

# 2. 补全每个id的所有固定时间步
full_index = pd.MultiIndex.from_product(
    [df['id'].unique(), fixed_time_slots],
    names=['id', 'time_slot']
)
df_filled = df.set_index(['id', 'time_slot']).reindex(full_index).reset_index()

# 3. 补全date列(若不需要保留date列可跳过此步)
base_date = df['date'].dt.date.iloc[0]
df_filled['date'] = pd.to_datetime(base_date.astype(str) + ' ' + df_filled['time_slot'])

# 4. 长表转宽表
result = df_filled.pivot(index='id', columns='time_slot', values='val').reset_index()
# 重命名列,方便识别
result.columns = ['id'] + [f'val_{slot}' for slot in fixed_time_slots]

运行后输出结果:

id  val_06:00  val_06:15  val_06:30  val_06:45  val_07:00
0   1       11.0       10.0       12.0        3.0        4.0
1   2        5.0        NaN      125.0       45.0        NaN
2   3       31.0       -2.0        NaN        NaN        NaN

方法2:精简版(仅适配单日期场景)

如果确定所有数据属于同一日期,不需要补全date字段,可以直接透视后补全缺失列,代码更短:

df['date'] = pd.to_datetime(df['date'])
df['time_slot'] = df['date'].dt.strftime('%H:%M')
fixed_time_slots = ['06:00', '06:15', '06:30', '06:45', '07:00']

result = df.pivot(index='id', columns='time_slot', values='val')
result = result.reindex(columns=fixed_time_slots).reset_index()
result.columns = ['id'] + [f'val_{slot}' for slot in fixed_time_slots]

输出结果和方法1完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:36:19