Pandas处理:类别与子项标签同列的Excel数据逆透视
Pandas实现分层标签DataFrame的结构转换
可以通过Pandas内置方法的组合来实现这个需求,核心思路是先标记分层标签、拆分数据后透视,再合并汇总行,以下是具体实现步骤:
1. 模拟输入数据
先构造一个和你描述结构一致的示例DataFrame:
import pandas as pd # 模拟从Excel导入的原始数据 raw_data = { 'Row Labels': ['Collection A', 'Data1', 'Data2', 'Collection B', 'Data1', 'Total'], 'Sum': [None, 10, 20, None, 15, 45] } df = pd.DataFrame(raw_data)
2. 标记并填充分层标签
用ffill()向前填充Collection标签,同时标记Total汇总行:
# 标记Collection分组标签,空值(Sum为None且非Total行)的Row Labels作为分组依据 df['Collection'] = df['Row Labels'].where(df['Sum'].isna() & df['Row Labels'] != 'Total').ffill() # 标记Total行 df['is_total'] = df['Row Labels'] == 'Total'
3. 拆分数据并透视子项
将子项数据(Data1、Data2)透视成列,缺失值填充0:
# 提取非Total的Data子项数据 sub_items = df[~df['is_total'] & df['Row Labels'].str.startswith('Data')] # 透视转换:Collection为行,Data1/Data2为列 pivot_result = sub_items.pivot( index='Collection', columns='Row Labels', values='Sum' ).fillna(0).reset_index()
4. 处理Total汇总行并合并
构造符合结构的Total行,和透视结果合并:
# 提取Total行的Sum值,构造对应结构 total_row = pd.DataFrame({ 'Collection': ['Total'], 'Data1': [0], 'Data2': [0], 'Sum': [df.loc[df['is_total'], 'Sum'].values[0]] }) # 合并最终结果 final_df = pd.concat([pivot_result, total_row], ignore_index=True)
替代实现方式(groupby+unstack)
也可以用groupby结合unstack完成透视,逻辑更紧凑:
# 标记分组标签 df['group'] = df['Row Labels'].where(df['Sum'].isna() & df['Row Labels'] != 'Total').ffill() # 分组透视子项数据 grouped_result = df[df['Row Labels'].str.startswith('Data')]\ .groupby(['group', 'Row Labels'])['Sum'].first()\ .unstack(fill_value=0).reset_index().rename(columns={'group':'Collection'}) # 构造并合并Total行 total_row = pd.DataFrame([{ 'Collection':'Total', 'Data1':0, 'Data2':0, 'Sum':df.loc[df['Row Labels']=='Total', 'Sum'].values[0] }]) final_df = pd.concat([grouped_result, total_row], ignore_index=True)
以上方案全部使用Pandas内置方法(ffill()、pivot()、groupby()、unstack()、concat()等),无需额外依赖,逻辑清晰且易于调整。
内容的提问来源于stack exchange,提问作者user3552225
相关产品推荐
相关产品推荐

