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

pandas扁平化MultiIndex列后移除索引列并设置DataFrame样式的方法

问题描述

我有一个包含3列的pandas示例DataFrame。
示例数据集代码如下:

In [3]: df = pd.DataFrame({
   ...:                     'mode': ['car'] * 4 + ['train'] * 3 + ['truck'] * 5,
   ...:                     'qty1': [2,4,9,7,6,3,4,1,2,5,5,7],
   ...:                     'qty2': [5,2,3,6,9,7,4,5,1,6,3,9]
   ...:                   })
   ...: df
Out[3]:
     mode  qty1  qty2
0     car     2     5
1     car     4     2
2     car     9     3
3     car     7     6
4   train     6     9
5   train     3     7
6   train     4     4
7   truck     1     5
8   truck     2     1
9   truck     5     6
10  truck     5     3
11  truck     7     9

使用pivot_table生成透视表,代码及输出如下:

In [4]: pivot1 = pd.pivot_table(data=df,
   ...:                         index=['mode'],
   ...:                         values=['qty1','qty2'],
   ...:                         aggfunc='sum')

In [5]: pivot1
Out[5]:
       qty1  qty2
mode
car      22    16
train    13    20
truck    20    24

随后对透视表应用样式设置,代码如下:

In [7]: pivot1 = pivot1.style.set_table_styles([
   ...:                           {
   ...:                                 "selector":"th",
   ...:                                 "props": [("border", "1px solid black"),
   ...:                                           ("font-style", "italic")]
   ...:                             },
   ...:                             {
   ...:                                 "selector":"th.row_heading",
   ...:                                 "props": [("border", "1px solid black"),
   ...:                                           ("font-style", "italic")]
   ...:                             }                           
   ...:                         ]).set_properties(border="1px solid black").format('${:.2f}')
   ...: pivot1

当前需要实现的效果是:所有列标题('mode'、'qty1'、'qty2')处于同一层级。曾尝试使用reset_index()重置索引,但重置后会出现多余的默认索引列,无法得到预期效果。预期最终表格结构为:

  • 表头依次为mode、qty1、qty2
  • 三行数据分别对应car、train、truck的聚合值
  • qty1、qty2列保留${:.2f}的美元格式
  • 所有单元格带1px黑色实线边框、表头为斜体

最终目标是将处理完成的表格保存为png/jpg格式,通过Python导入到pptx演示文稿中。

实现方案

步骤1:调整透视表结构并应用正确样式

核心解决思路是透视表生成后将行索引转为普通列,同时隐藏pandas默认生成的数字索引,即可让所有表头处于同一层级,且不会出现多余列。

import pandas as pd

# 生成原始示例数据
df = pd.DataFrame({
    'mode': ['car'] * 4 + ['train'] * 3 + ['truck'] * 5,
    'qty1': [2,4,9,7,6,3,4,1,2,5,5,7],
    'qty2': [5,2,3,6,9,7,4,5,1,6,3,9]
})

# 生成透视表后重置索引,将mode从行索引转为普通列
pivot1 = pd.pivot_table(
    data=df,
    index=['mode'],
    values=['qty1','qty2'],
    aggfunc='sum'
).reset_index()

# 应用样式
styled_pivot = pivot1.style.hide(axis='index') \
    .set_table_styles([
        # 表头样式:1px黑边、斜体
        {
            "selector": "th",
            "props": [("border", "1px solid black"), ("font-style", "italic")]
        },
        # 普通单元格样式:1px黑边
        {
            "selector": "td",
            "props": [("border", "1px solid black")]
        }
    ]) \
    # 仅对数值列设置美元格式,避免mode列被错误格式化
    .format({
        'qty1': '${:.2f}',
        'qty2': '${:.2f}'
    })

# 预览效果
styled_pivot

关键参数说明:

  • reset_index():将原本作为行索引的mode列转为普通数据列,和qty1/qty2列处于同一表头层级
  • .hide(axis='index'):隐藏pandas默认生成的数字行索引,不会出现多余的无标题列
  • 传入字典给format():单独指定需要应用美元格式的列,避免文本列mode被错误添加货币符号

步骤2:导出样式表为图片

推荐使用dataframe_image库导出,对pandas Style样式的兼容性最好,不会丢失边框、字体、格式设置。
先安装依赖:

pip install dataframe_image

导出代码:

import dataframe_image as dfi

# 导出为PNG格式,设置dpi=200保证图片清晰度
dfi.export(styled_pivot, 'styled_pivot_table.png', dpi=200)

步骤3:将图片插入PPTX文件

使用python-pptx库实现自动插入,先安装依赖:

pip install python-pptx

插入代码示例:

from pptx import Presentation
from pptx.util import Inches

# 新建空白演示文稿
prs = Presentation()
# 选择空白版式幻灯片
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# 设置图片位置(距幻灯片左上角1英寸)和宽度(6英寸,高度自动等比缩放)
left = Inches(1)
top = Inches(1)
pic_width = Inches(6)
slide.shapes.add_picture('styled_pivot_table.png', left, top, width=pic_width)

# 保存最终PPT文件
prs.save('带表格的演示文稿.pptx')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:01:41