Python pandas透视表问题:按客户分组汇总文件组数据失败
问题:Pandas透视表无法按CustomerName分组汇总FileGroup数据
原代码与问题
用户期望按CustomerName分组,汇总不同FileGroup的大小数据,但原透视表代码未生效:
def consolidated_df(): df = breakdown_df() df.pivot_table(index='CustomerName', columns='FileGroup', aggfunc="sum") return df
原始DataFrame结构:
ID CustomerName FileGroup Size Size(Bytes) 1 CustomerA Database 99.8 M 104667648 1 CustomerA Database 99.8 M 104667648 1 CustomerA Backup 99.8 M 104667648 1 CustomerA Backup 99.8 M 104667648 1 CustomerA Site 99.8 M 104667648 1 CustomerA Site 99.8 M 104667648 2 CustomerB Database 99.8 M 104667648 2 CustomerB Database 99.8 M 104667648 2 CustomerB Backup 99.8 M 104667648 2 CustomerB Backup 99.8 M 104667648 2 CustomerB Site 99.8 M 104667648 2 CustomerB Site 99.8 M 104667648
期望输出格式:
ID CustomerName DatabaseSize DatabaseSizeBytes BackupSize BackupSizeBytes SiteSize SiteSizeBytes TotalSize 1 CustomerA [Total Size] [Total Size Bytes] [TotalSize] [Total Size Bytes] [Total Site Size] [Total Site Bytes] [Total Bytes for everything] 2 CustomerB [Total Size] [Total Size Bytes] [TotalSize] [Total Size Bytes] [Total Site Size] [Total Site Bytes] [Total Bytes for everything]
问题分析
- 未接收透视表结果:原代码调用
pivot_table后没有将结果赋值给df,直接返回原始数据,导致透视表操作无效。 - 多级列处理:默认
pivot_table会生成多级列(如(Size(Bytes), Database)),需要扁平化列名以匹配期望格式。 - ID字段合并:原始数据中同一
CustomerName对应相同ID,需要保留该字段。 - TotalSize计算:需要汇总所有FileGroup的字节数得到总大小。
修正代码
def consolidated_df(): df = breakdown_df() # 生成透视表,对Size(Bytes)求和,保留CustomerName和ID pivot_df = df.pivot_table( index=['CustomerName', 'ID'], columns='FileGroup', values='Size(Bytes)', aggfunc='sum' ).reset_index() # 扁平化列名,重命名为目标格式 pivot_df.columns = ['CustomerName', 'ID', 'DatabaseSizeBytes', 'BackupSizeBytes', 'SiteSizeBytes'] # 计算总字节数 pivot_df['TotalSize'] = pivot_df[['DatabaseSizeBytes', 'BackupSizeBytes', 'SiteSizeBytes']].sum(axis=1) # 将字节数转换为易读的Size格式(如MB) def bytes_to_human(size): return f"{size / (1024**2):.1f} M" pivot_df['DatabaseSize'] = pivot_df['DatabaseSizeBytes'].apply(bytes_to_human) pivot_df['BackupSize'] = pivot_df['BackupSizeBytes'].apply(bytes_to_human) pivot_df['SiteSize'] = pivot_df['SiteSizeBytes'].apply(bytes_to_human) # 调整列顺序匹配期望格式 final_cols = [ 'ID', 'CustomerName', 'DatabaseSize', 'DatabaseSizeBytes', 'BackupSize', 'BackupSizeBytes', 'SiteSize', 'SiteSizeBytes', 'TotalSize' ] pivot_df = pivot_df[final_cols] return pivot_df
代码说明
- 透视表指定
index包含CustomerName和ID,确保每个客户的ID被保留。 - 重命名列名时直接映射到目标格式,避免多级列的混乱。
- 通过字节数计算易读的
Size字段,避免直接求和字符串类型的Size列。 - 最后调整列顺序,完全匹配期望的输出结构。
内容的提问来源于stack exchange,提问作者uncrayon
相关产品推荐
相关产品推荐

