Pandas长表转宽表时重复索引取均值问题及解法
解决重复日期索引下长转宽保留原始数值的问题
当使用pivot_table处理含重复日期索引的长格式DataFrame时,默认会对重复的index+columns组合做聚合(默认是均值),如果想要保留所有原始行的数值且不新增永久唯一ID,可以按以下步骤操作:
问题复现
先看你的场景示例代码:
import pandas as pd data = { 'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02', '2023-01-02'], 'category': ['A', 'B', 'A', 'B', 'A'], 'value': [10, 20, 30, 40, 50] } df = pd.DataFrame(data) # 用pivot_table得到聚合后的均值结果 pivot_result = df.pivot_table(index='date', columns='category', values='value') print(pivot_result)
输出结果(均值聚合):
A B date 2023-01-01 10 20.0 2023-01-02 40 40.0
解决方案
通过临时添加组内序号来构建唯一的多级索引,完成转宽后再移除临时序号,最终保留原始日期索引和所有数值:
# 给每个(date, category)组合添加组内序号(临时用,最终不会保留) df['temp_seq'] = df.groupby(['date', 'category']).cumcount() # 用date+temp_seq作为唯一索引转宽,再移除temp_seq索引 wide_df = df.pivot(index=['date', 'temp_seq'], columns='category', values='value').reset_index(level='temp_seq', drop=True) print(wide_df)
输出结果(保留所有原始行):
A B date 2023-01-01 10 20.0 2023-01-02 30 40.0 2023-01-02 50 NaN
原理说明
groupby(['date', 'category']).cumcount()会为每个重复的date+category组合生成从0开始的序号,让date+temp_seq成为唯一的多级索引,避免转宽时触发聚合;- 转宽后通过
reset_index(level='temp_seq', drop=True)移除临时序号,还原回原始的日期索引,最终结果里不会留下新增的ID列; - 这种方法既满足了保留重复日期索引的需求,又没有在最终结果中新增额外的唯一ID列。
内容的提问来源于stack exchange,提问作者Chronicles
相关产品推荐
相关产品推荐

