如何在Pandas中将单日多行数据合并为单行多列结构
解决方案:将按小时的DataFrame按天重塑为宽表
核心思路
利用Pandas的**数据重塑(Reshape)**功能,直接将按小时分布的行数据转换为按天聚合的宽表,无需手动循环创建列并填充,高效且兼容字符串、数值等多种数据类型。
完整实现代码
import pandas as pd import numpy as np # 1. 创建测试数据(兼容字符串和数值类型) timestamps = pd.date_range(start=pd.Timestamp.now().floor('H'), periods=100, freq='H') df = pd.DataFrame({ 'timestamp': timestamps, 'value1': np.where(timestamps.hour % 2 == 0, 'abc', np.random.randn(100)), 'value2': np.where(timestamps.hour % 3 == 0, 'def', np.random.randint(0, 10, 100)) }) # 2. 提取分组键和小时标识 df['date'] = df['timestamp'].dt.date # 按日期分组 df['hour'] = df['timestamp'].dt.strftime('%H') # 格式化为00-23的两位小时字符串 # 3. 重塑数据为宽表 pivoted = df.pivot(index='date', columns='hour', values=['value1', 'value2']) # 4. 重命名列名为目标格式(value1_00、value2_00...) pivoted.columns = [f'{metric}_{hour}' for metric, hour in pivoted.columns] # 5. 添加当天的首个timestamp列,并调整列顺序 pivoted['timestamp'] = df.groupby('date')['timestamp'].first() result = pivoted.reset_index(drop=True) # 确保timestamp列在最前面 result = result[['timestamp'] + [col for col in result.columns if col != 'timestamp']] # 查看结果 print(result.head())
关键步骤说明
提取日期和小时:
- 用
dt.date提取日期作为分组依据,确保同一天的数据聚合到一行。 - 用
dt.strftime('%H')将小时格式化为两位字符串(如00、01),直接对应目标列名的后缀。
- 用
Pivot重塑:
pivot函数自动按date分组,将hour作为列维度,value1和value2作为值,直接生成包含所有小时列的宽表。- 此方法天然兼容字符串、数值等混合数据类型,无需额外处理。
列名整理:
- 利用MultiIndex的特性,将原列的(指标名,小时)组合重命名为
指标名_小时的格式,完全匹配需求。
- 利用MultiIndex的特性,将原列的(指标名,小时)组合重命名为
补充timestamp列:
- 通过
groupby取每组(每天)的第一个timestamp,作为该行的时间标识。
- 通过
优势对比
- 替代手动循环:无需预先创建空列再逐个填充,代码更简洁,执行效率更高。
- 兼容性强:自动处理缺失小时(对应列值为
NaN),同时支持字符串、数值等多种数据类型。
内容的提问来源于stack exchange,提问作者Kw3rtie
相关产品推荐
相关产品推荐

