如何重塑包含重复值的Pandas天气数据DataFrame?
长格式天气DataFrame转宽格式并补全时间序列方案
原始数据格式
category fcstValue Timestamp 0 TMP 13.0 2022-10-05 06:00:00 3 VEC 62.0 2022-10-05 06:00:00 4 WSD 1.7 2022-10-05 06:00:00 5 SKY 4.0 2022-10-05 06:00:00 6 PTY 0.0 2022-10-05 06:00:00 10 REH 85.0 2022-10-05 06:00:00 12 TMP 14.0 2022-10-05 07:00:00 15 VEC 80.0 2022-10-05 07:00:00 16 WSD 1.7 2022-10-05 07:00:00 17 SKY 4.0 2022-10-05 07:00:00
目标格式
Timestamp TMP VEC WSD SKY PTY REH SNO 2022-10-05 00:00:00 2022-10-05 00:01:00 2022-10-05 00:02:00 2022-10-05 00:03:00 2022-10-05 00:04:00 2022-10-05 00:05:00 2022-10-05 06:00:00 13 62 1.7 4 0 85 -
解决方案
核心步骤
- 用透视表替代普通透视,解决重复值问题
pivot要求Timestamp+category组合唯一,否则报错,改用pivot_table并指定聚合函数(如first),即使存在重复组合也能正常处理:
pivoted = df.pivot_table(index='Timestamp', columns='category', values='fcstValue', aggfunc='first')
- 生成完整时间序列并补全
先确保时间列是datetime类型,再生成当天每分钟的时间索引,重新索引透视后的DataFrame补全缺失时间点:
# 转换时间列格式 df['Timestamp'] = pd.to_datetime(df['Timestamp']) # 生成当天00:00到23:59的每分钟时间序列 start_time = df['Timestamp'].min().floor('D') end_time = start_time + pd.Timedelta(days=1) - pd.Timedelta(minutes=1) full_time_index = pd.date_range(start=start_time, end=end_time, freq='min') # 补全时间点 result = pivoted.reindex(full_time_index)
- 补充缺失列并填充默认值
目标中的SNO列原始数据不存在,直接添加并填充默认值,其他缺失值统一填充为-:
# 添加SNO列 result['SNO'] = '-' # 填充所有缺失值为'-' result = result.fillna('-')
- 调整列顺序(可选)
按目标格式调整列的排列顺序:
target_cols = ['TMP', 'VEC', 'WSD', 'SKY', 'PTY', 'REH', 'SNO'] result = result[target_cols]
完整代码
import pandas as pd # 构造示例数据 data = [ ['TMP', 13, '2022-10-05 06:00:00'], ['VEC', 62, '2022-10-05 06:00:00'], ['WSD', 1.7, '2022-10-05 06:00:00'], ['SKY', 4, '2022-10-05 06:00:00'], ['PTY', 0, '2022-10-05 06:00:00'], ['REH', 85, '2022-10-05 06:00:00'], ['TMP', 14, '2022-10-05 07:00:00'], ['VEC', 80, '2022-10-05 07:00:00'], ['WSD', 1.7, '2022-10-05 07:00:00'], ['SKY', 4, '2022-10-05 07:00:00'], ] df = pd.DataFrame(data, columns=['category', 'fcstValue', 'Timestamp']) # 执行转换流程 df['Timestamp'] = pd.to_datetime(df['Timestamp']) pivoted = df.pivot_table(index='Timestamp', columns='category', values='fcstValue', aggfunc='first') start_time = df['Timestamp'].min().floor('D') end_time = start_time + pd.Timedelta(days=1) - pd.Timedelta(minutes=1) full_time_index = pd.date_range(start=start_time, end=end_time, freq='min') result = pivoted.reindex(full_time_index) result['SNO'] = '-' result = result.fillna('-') target_cols = ['TMP', 'VEC', 'WSD', 'SKY', 'PTY', 'REH', 'SNO'] result = result[target_cols] # 查看前7行结果 print(result.head(7))
常见问题说明
- pivot报错:因为
pivot要求索引+列的组合唯一,若存在重复的Timestamp+category记录就会报错,pivot_table通过聚合函数可以规避这个问题。 - groupby后转宽格式:也可以用
groupby+unstack实现,效果和透视表一致:df.groupby(['Timestamp', 'category'])['fcstValue'].first().unstack() - 空DataFrame问题:大概率是
Timestamp列未转为datetime类型,或者透视时参数设置错误,确保时间列格式正确是关键。
内容的提问来源于stack exchange,提问作者Abdullah
相关产品推荐
相关产品推荐

