You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Pandas将原始数据重排为报表格式(含多限额场景)

Pandas 实现分层报表格式转换

一、基础场景实现

针对单个客户对应统一限额的场景,我们需要生成「客户汇总行+账户明细行」的分层结构:汇总行展示客户信息、总余额,明细行展示单个账户信息。

实现代码

import pandas as pd

# 原始数据
d = {'Customer Name': ['A', 'A', 'B', 'C', 'C', 'C'], 
     'ID_NO': ['AA', 'AA', 'BB', 'CC', 'CC', 'CC'],
     'Account Number': ['123456', '123457', '234567', '345678', '345679', '345680'],
     'Limit': [1000, 1000, 900, 1200, 1200, 1200], 
     'Balance': [400, 600, 800, 300, 400, 200]}
df = pd.DataFrame(data=d)

# 生成客户汇总行:按客户+ID分组,计算总余额,保留限额值
summary_rows = df.groupby(['Customer Name', 'ID_NO'], as_index=False).agg(
    Limit=('Limit', 'first'),
    Balance=('Balance', 'sum')
)
# 分配排序标识,确保汇总行排在对应明细行前
summary_rows['sort_key'] = df.groupby(['Customer Name']).ngroup() * 2

# 生成账户明细行:重命名账户列为客户名,清空ID和限额列
detail_rows = df[['Account Number', 'Balance']].rename(columns={'Account Number': 'Customer Name'})
detail_rows['ID_NO'] = ''
detail_rows['Limit'] = ''
# 分配明细行排序标识,跟在对应汇总行后
detail_rows['sort_key'] = df.groupby(['Customer Name']).ngroup() * 2 + 1

# 合并数据并排序,整理列顺序
result = pd.concat([summary_rows, detail_rows]).sort_values('sort_key').drop('sort_key', axis=1)
result = result[['Customer Name', 'ID_NO', 'Limit', 'Balance']].reset_index(drop=True)

print(result)

输出说明

生成的结果与你期望的df2结构完全一致:每个客户的汇总行在前,显示客户名称、ID、限额及总余额;后续行显示对应账户号,ID和限额列为空,余额为单个账户数值。


二、多限额场景实现

当单个客户存在多个Limit Number时,需要按客户-限额组生成分层结构:每个限额组对应一个汇总行,下方是该组的账户明细。

实现代码

import pandas as pd

# 多限额原始数据
d = {'Customer Name': ['A', 'A', 'B', 'C', 'C', 'C'], 
     'ID_NO': ['AA', 'AA', 'BB', 'CC', 'CC', 'CC'],
     'Limit Number': ['AAA', 'AAA', 'BBB', 'CCC', 'CCC', 'CCD'],
     'Account Number': ['123456', '123457', '234567', '345678', '345679', '345680'],
     'Limit': [1000, 1000, 900, 1200, 1200, 1500], 
     'Balance': [400, 600, 800, 300, 400, 600]}
df = pd.DataFrame(data=d)

# 生成限额组汇总行:按客户+ID+限额编号分组,计算组内总余额,保留限额值
summary_rows = df.groupby(['Customer Name', 'ID_NO', 'Limit Number'], as_index=False).agg(
    Limit=('Limit', 'first'),
    Balance=('Balance', 'sum')
)
# 分配排序标识:每个限额组对应唯一编号,汇总行用偶数编号
summary_rows['sort_key'] = df.groupby(['Customer Name', 'Limit Number']).ngroup() * 2

# 生成账户明细行:替换客户名为账户号,清空ID和限额列
detail_rows = df.copy()
detail_rows['Customer Name'] = detail_rows['Account Number']
detail_rows['ID_NO'] = ''
detail_rows['Limit'] = ''
# 分配明细行排序标识:对应限额组的奇数编号,确保跟在汇总行后
detail_rows['sort_key'] = df.groupby(['Customer Name', 'Limit Number']).ngroup() * 2 + 1
detail_rows = detail_rows[['Customer Name', 'ID_NO', 'Limit', 'Balance', 'sort_key']]

# 合并并排序数据,整理最终列顺序
result = pd.concat([summary_rows, detail_rows]).sort_values('sort_key').drop('sort_key', axis=1)
result = result[['Customer Name', 'ID_NO', 'Limit', 'Balance']].reset_index(drop=True)

print(result)

逻辑说明

  1. 通过groupby(['Customer Name', 'Limit Number']).ngroup()给每个客户下的限额组分配唯一组号,确保排序时组内顺序正确
  2. 汇总行使用组号2,明细行使用组号2+1,保证每组汇总行始终在其明细行之前
  3. 最终合并后按sort_key排序,得到符合需求的分层报表结构

内容的提问来源于stack exchange,提问作者hoa tran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:07:28