pandas groupby算小计:如何将索引Subtotal移至code列并排序索引
实现目标的调整方案
核心需要改动两个逻辑根源:
- 移除原来将"Subtotal"、"GrandTotal"直接作为行索引的写法,这是导致标识出现在索引列的根本原因
- 把这两个标识作为值填充到
code列的对应行,同时保持索引连续有序。
分步操作说明
- 调整分组小计的生成逻辑
原来写group.loc['subtotal'] = ...的写法,本质是新增了一个索引名为subtotal的行,才会把字样显示在索引列。修改时,单独构造小计行的DataFrame,在code列填入Subtotal,数值列填入对应分组的求和结果,行索引取当前分组内最大索引值+1,保证索引连续。 - 调整总计行的生成逻辑
原来直接df_subtotal.loc['GrandTotal'] = ...同理会把字样放到索引上,修改为构造独立的总计行,在code列填入GrandTotal,索引取全表最大索引值+1。 - 排序逻辑
所有行拼接完成后按索引值升序排列,保证顺序为「分组1明细行→分组1小计行→分组2明细行→分组2小计行→……→全表总计行」,符合预期展示效果。
修改后可直接运行的参考代码
def subtotal(df__, sheet_name, writer): container = [] # 分组时保持原数据顺序,不自动重排 for key, group in df__.groupby(['key'], sort=False): container.append(group) # 构造分组小计行,不再将"Subtotal"设为索引 subtotal_row = pd.DataFrame( data={ 'quantity': group['quantity'].sum(), 'quantity2': group['quantity2'].sum(), 'quantity3': group['quantity3'].sum(), # 将Subtotal标识写入code列 'code': 'Subtotal' }, index=[group.index.max() + 1] ) container.append(subtotal_row) # 拼接明细+分组小计行 df_subtotal = pd.concat(container) # 构造全表总计行,不再将"GrandTotal"设为索引 grandtotal_row = pd.DataFrame( data={ 'quantity': df__['quantity'].sum(), 'quantity2': df__['quantity2'].sum(), 'quantity3': df__['quantity3'].sum(), # 将GrandTotal标识写入code列 'code': 'GrandTotal' }, index=[df_subtotal.index.max() + 1] ) df_subtotal = pd.concat([df_subtotal, grandtotal_row]) # 按索引排序,保证行顺序符合展示要求 df_subtotal = df_subtotal.sort_index() # 导出Excel,可根据需求选择是否保留索引列 df_subtotal.to_excel(writer, sheet_name=sheet_name, index=False) return
效果校验要点
- 索引列无游离的"Subtotal"、"GrandTotal"字样,保持连续的数字顺序
- 每个分组明细下方的行,
code列会显示"Subtotal",对应三个数值列为分组求和结果 - 表格最后一行
code列显示"GrandTotal",对应三个数值列为全表求和结果
内容的提问来源于stack exchange,提问作者ja c
相关产品推荐
相关产品推荐

