无需唯一行索引实现Pandas DataFrame透视转换
问题解答
核心结论
不推荐使用pivot_table——它的核心逻辑是对重复键进行聚合(即使指定aggfunc='first'也会合并重复组),而你需要保留所有原始重复行,因此应该用Pandas的数据重塑方法而非聚合工具。
具体实现方法
无需添加虚构的Contract Index辅助列,直接通过以下步骤转换:
情况1:目标字段(Treaty Year/Currency/Class)在行的多层索引中
假设你的原始DataFrame行索引是多层结构,列是Placed/Attachment/Limit:
# 模拟原始数据 import pandas as pd idx = pd.MultiIndex.from_tuples( [(2023, 'USD', 'Property'), (2023, 'USD', 'Property'), (2022, 'EUR', 'Casualty')], names=['Treaty Year', 'Currency', 'Class'] ) df = pd.DataFrame( [[100000, 5000, 2000000], [150000, 7500, 3000000], [80000, 4000, 1500000]], index=idx, columns=['Placed', 'Attachment', 'Limit'] ) # 直接转换:多层索引转普通列,自动保留重复行 result = df.reset_index()
转换后result就是你要的格式,包含所有重复的Treaty Year/Currency/Class组合。
情况2:目标字段在列的多层索引中
如果原始DataFrame的列是多层结构(比如第一层是Treaty Year/Currency/Class,第二层是字段名):
# 模拟原始数据 cols = pd.MultiIndex.from_tuples( [(2023, 'USD', 'Property', 'Placed'), (2023, 'USD', 'Property', 'Attachment'), (2023, 'USD', 'Property', 'Limit'), (2023, 'USD', 'Property', 'Placed'), (2023, 'USD', 'Property', 'Attachment'), (2023, 'USD', 'Property', 'Limit')], names=['Treaty Year', 'Currency', 'Class', 'Field'] ) df = pd.DataFrame([[100000,5000,2000000,150000,7500,3000000]], columns=cols) # 转换:先堆叠列的前3层到行,再重塑结构 result = df.stack(level=[0,1,2]).reset_index() result = result.pivot(index=['level_0', 'Treaty Year', 'Currency', 'Class'], columns='Field', values=0).reset_index(drop=True)
同样不需要辅助列,直接保留所有重复的组合行。
关键提醒
- 所有重塑方法(
reset_index/stack/melt)都会保留原始数据的行数,不会合并重复的键组合,完全满足你的需求。 pivot_table仅适用于需要对重复键进行统计聚合(求和/均值等)的场景,不适合单纯的结构转换。
内容的提问来源于stack exchange,提问作者Tommo
相关产品推荐
相关产品推荐

