如何按Server分组并在每组末尾添加求和行汇总Pandas DataFrame
Pandas分组后在每组末尾添加汇总行的实现方案
需求说明
需要对给定的Pandas DataFrame按server字段分组,实现以下要求:
- 数值列(
ports、connected、disabled)求和 - 非数值列保留每组最后一行的值
- 不显示
slot列 - 每组末尾添加汇总行
- 组与组之间插入空行
原始DataFrame
import pandas as pd # 构造原始数据 data = { 'Env': ['Prod', 'Prod', 'Prod', 'Prod', 'Dev', 'Dev', 'Dev', 'Dev'], 'location': ['USA', 'USA', 'USA', 'USA', 'EMEA', 'EMEA', 'EMEA', 'EMEA'], 'lob': ['Market', 'Market', 'Market', 'Market', 'Ins.', 'Ins.', 'Ins.', 'Ins.'], 'grid': ['AB3', 'AB3', 'AB3', 'AB3', 'AB6', 'AB6', 'AB6', 'AB6'], 'row': ['bc2', 'bc2', 'bc2', 'bc2', 'bc4', 'bc4', 'bc4', 'bc4'], 'server': ['Server123', 'Server123', 'Server123', 'Server123', 'Serverabc', 'Serverabc', 'Serverabc', 'Serverabc'], 'model': ['Hitachi', 'Hitachi', 'Hitachi', 'Hitachi', 'IBM', 'IBM', 'IBM', 'IBM'], 'make': ['Stor', 'Stor', 'Stor', 'Stor', 'Mfa', 'Mfa', 'Mfa', 'Mfa'], 'slot': [1, 2, 3, 4, 1, 2, 3, 4], 'ports': [3, 2, 0, 8, 6, 8, 12, 10], 'connected': [1, 3, 0, 7, 5, 4, 4, 2], 'disabled': [5, 3, 2, 1, 0, 0, 0, 0] } df = pd.DataFrame(data) print(df)
输出:
Env location lob grid row server model make slot ports connected disabled 0 Prod USA Market AB3 bc2 Server123 Hitachi Stor 1 3 1 5 1 Prod USA Market AB3 bc2 Server123 Hitachi Stor 2 2 3 3 2 Prod USA Market AB3 bc2 Server123 Hitachi Stor 3 0 0 2 3 Prod USA Market AB3 bc2 Server123 Hitachi Stor 4 8 7 1 4 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 1 6 5 0 5 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 2 8 4 0 6 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 3 12 4 0 7 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 4 10 2 0
期望输出效果
Env location lob grid row server model make ports connected disabled 0 Prod USA Market AB3 bc2 Server123 Hitachi Stor 3 1 5 1 Prod USA Market AB3 bc2 Server123 Hitachi Stor 2 3 3 2 Prod USA Market AB3 bc2 Server123 Hitachi Stor 0 0 2 3 Prod USA Market AB3 bc2 Server123 Hitachi Stor 8 7 1 4 Total USA Market AB3 bc2 Server123 Hitachi Stor 13 11 11 5 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 6 5 0 6 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 8 4 0 7 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 12 4 0 8 Dev EMEA Ins. AB6 bc4 Serverabc IBM Mfa 10 2 0 9 Total EMEA Ins. AB6 bc4 Serverabc IBM Mfa 36 15 0
用户尝试的问题
用户仅通过groupby.sum()只能得到数值列的汇总结果,无法将汇总行插入每组末尾:
df2 = df.groupby('server').sum()
解决方案
通过分组遍历、生成汇总行、合并数据的方式实现需求,代码如下:
import pandas as pd # 1. 区分数值列和非数值列,排除slot列 numeric_cols = ['ports', 'connected', 'disabled'] non_numeric_cols = [col for col in df.columns if col not in numeric_cols + ['slot']] output_cols = non_numeric_cols + numeric_cols # 2. 初始化结果列表 result = [] # 3. 按server分组处理 for server, group in df.groupby('server'): # 添加当前组数据(移除slot列) result.append(group[output_cols]) # 生成汇总行:非数值列取组内最后一行,数值列求和,Env改为Total summary_data = group[non_numeric_cols].iloc[-1].to_dict() summary_data['Env'] = 'Total' summary_data.update(group[numeric_cols].sum().to_dict()) summary_df = pd.DataFrame([summary_data], columns=output_cols) result.append(summary_df) # 添加组间空行 empty_row = pd.DataFrame([[pd.NA]*len(output_cols)], columns=output_cols) result.append(empty_row) # 4. 合并所有数据,移除末尾多余空行 df_final = pd.concat(result, ignore_index=True).dropna(how='all') # 5. 输出结果 print(df_final)
代码说明
- 先明确需要保留的列,排除不需要显示的
slot列 - 遍历每个分组,先将当前组数据加入结果
- 生成汇总行:复用组内最后一行的非数值字段,对数值字段求和,将
Env改为Total - 每组后插入空行,最后合并所有数据并清理末尾的空行
内容的提问来源于stack exchange,提问作者user1471980
相关产品推荐
相关产品推荐

