Pandas按id和日期分组补全时间步转固定列宽表的方法
问题原因
你原有代码无法生成固定5列的核心原因有两点:
- 没有提前补全每个
id+日期分组下缺失的固定时间步,直接按实际存在的时间点做透视 - 透视时使用带日期的完整时间戳作为列维度,不同日期的同个时间点会被识别为独立列,最终列数随数据动态变化
正确实现代码
import pandas as pd from itertools import product # 预处理时间字段 df['date'] = pd.to_datetime(df['date']) df['dates'] = df['date'].dt.date # 定义规则要求的5个固定时间步 fixed_time_list = [ pd.to_datetime('06:00:00').time(), pd.to_datetime('06:15:00').time(), pd.to_datetime('06:30:00').time(), pd.to_datetime('06:45:00').time(), pd.to_datetime('07:00:00').time() ] # 生成所有(id、日期、固定时间)的完整组合索引 all_id = df['id'].unique() all_date = df['dates'].unique() full_combination = pd.DataFrame( product(all_id, all_date, fixed_time_list), columns=['id', 'dates', 'time'] ) full_combination['full_datetime'] = pd.to_datetime( full_combination['dates'].astype(str) + ' ' + full_combination['time'].astype(str) ) # 左连接原数据,缺失时间步的val值自动填充为NaN df_complete = full_combination.merge( df[['id', 'date', 'val']], left_on=['id', 'full_datetime'], right_on=['id', 'date'], how='left' ) # 透视得到固定5列结果 final_df = df_complete.pivot(index=['id', 'dates'], columns='time', values='val') final_df.columns = [f'val{i+1}' for i in range(5)] final_df = final_df.reset_index()
结果说明
运行后输出的final_df会固定包含id、dates、val1~val5共7列:
- val1对应当天6:00的数值
- val2对应当天6:15的数值
- val3对应当天6:30的数值
- val4对应当天6:45的数值
- val5对应当天7:00的数值
缺失的时间步对应位置自动填充为NaN,和示例数据的预期完全匹配。
内容的提问来源于stack exchange,提问作者Sadcow
相关产品推荐
相关产品推荐

