Python 用 pandas 批量处理 Excel 数据透视表:从 pivot_table 到多文件汇总

雨后青山
雨后青山
发布时间:2026-08-23 | 169人浏览过
原创

前言

Excel 里的数据透视表很适合临时分析,但一旦报表数量变多,手工拖拽字段就会变成高频重复劳动。用 pandas 的 pivot_table 可以把同样的汇总逻辑写成脚本,再配合批量读取和导出,把多个文件、多个 Sheet 甚至整本工作簿的透视处理一次跑完。

Excel 数据透视表的优势,在于能把零散数据迅速整理成可读报表;但一旦面对几十个文件、多个工作表,手工拖拽就会变成重复劳动。用 pandas 的 pivot_table,可以把 Excel 里“行、列、值、汇总”的操作写成可复用代码,再进一步扩展到批量读取、统一汇总和自动导出。

这篇文章先从最基础的透视写法讲起,再逐步补到多级索引、多种统计方式,以及几种常见的批量处理场景。看完后,你可以判断自己更适合直接用 pandas 生成结果文件,还是在需要保留 Excel 工作簿交互时引入 xlwings。

先把 Excel 透视表翻译成 pandas 参数

如果你平时习惯在 Excel 里拖拽字段,那么理解 pivot_table 最快的方法,就是把它和 Excel 透视表的区域一一对应起来。

展示 Excel 透视表区域与 pandas pivot_table 参数对应关系的白底信息图
Excel 透视区域与 pandas 参数对把 Excel 透视区域和 pandas 参数放在一张图里,适合读者快速建立字段映射。
import pandas as pd

df = pd.read_excel("销售数据.xlsx")

pivot = pd.pivot_table(
    df,
    values="销售额",
    index="城市",
    columns="品类",
    aggfunc="sum",
    fill_value=0,
    margins=True,
    margins_name="合计"
)

这段代码完成的事情和 Excel 里的透视操作基本一致:

  • values="销售额":指定要汇总的数值列。
  • index="城市":把“城市”放到行标签。
  • columns="品类":把“品类”放到列标签。
  • aggfunc="sum":按求和方式聚合。
  • fill_value=0:把空值补成 0,避免结果里出现缺口。
  • margins=True 与 margins_name="合计":自动补出总计行和总计列。

如果只是把单个 Excel 表里的数据按某个维度汇总,这一段已经覆盖了大多数入门场景。

参数和 Excel 透视区域怎么对应

Excel 透视表区域 pandas pivot_table 参数 说明
行 index 作为行标签的列,可以是单列或多列。
列 columns 作为列标签的列。
值 values 需要进行聚合计算的数值列。
计算方式 aggfunc 聚合函数,如 'sum'、'mean'、'count'。
总计 margins True 或 False,决定是否显示总计行/列。
总计名称 margins_name 自定义总计行/列的标签,默认为 'All'。
空值填充 fill_value 将透视表中的空值替换为指定值。

需要更细维度时,怎么做多级透视和多统计值

实际业务很少只看一层汇总。你可能既要按城市看销售额,也要继续拆到销售员;或者既想看总和,又想看平均值和计数。这些都可以继续放在 pivot_table 里完成。

多级透视:一张表里展开更多维度

当行标签不止一列时,把 index 改成列表即可。

pivot = pd.pivot_table(
    df,
    values="销售额",
    index=["城市", "销售员"],
    columns="季度",
    aggfunc=["sum", "mean"]
)

这里的结果会出现层级索引:

  • 行索引先按“城市”,再按“销售员”细分。
  • 列索引按“季度”展开。
  • aggfunc=["sum", "mean"] 会同时生成求和和平均值两组结果。

这种结构特别适合做进一步分析,比如看同一城市不同销售员在各季度的表现差异。

多个统计值:一次输出总和、均值、计数和最大值

如果你只想按城市汇总,但希望一次看到多个统计指标,可以把 aggfunc 写成字典。

pivot = pd.pivot_table(
    df,
    values="销售额",
    index="城市",
    aggfunc={"销售额": ["sum", "mean", "count", "max"]}
)

这类写法适合“同一维度下看多种结果”的场景。输出表里,每个城市对应一行,而“销售额”下面会自动展开 sum、mean、count 和 max 四个子列。

原文还提到一个实用细节:这里的 values 参数实际上可以省略,因为 aggfunc 字典的键已经明确指定了计算列。

批量处理前,环境和基础库要准备什么

当你开始处理多个工作簿或多个 Sheet 时,核心思路就不只是“透视”,而是“读取 → 合并 → 透视 → 导出”。这一步先把依赖装好。

确保环境中已经安装 pandas 和 openpyxl:

pip install pandas openpyxl

常见导入方式如下,后面的文件批量匹配和路径处理会用到 glob 与 os:

import pandas as pd
import glob
import os

如果你的目标只是批量算结果并导出成新的 .xlsx 文件,这套组合通常就够用了。

四类常见批量场景,分别怎么写

下面几种场景,基本覆盖了用 pandas 批量替代 Excel 手工透视时最常见的需求。

展示多个 Excel 文件和多个 Sheet 合并后生成透视表的批量流程白底信息图
批量透视的主流程适合放在批量处理章节,强调“读取、合并、透视、导出”的主流程,以及文件名或 Sheet。

场景一:合并多个 Excel 文件后统一生成透视表

如果数据分散在多个以“销售数据_”开头的文件里,而且结构完全一致,最直接的方式就是先用 glob 找文件,再逐个读取后拼接,最后对合并后的总表做一次透视。

import pandas as pd
import glob
# 1. 获取所有Excel文件路径
file_paths = glob.glob('销售数据_*.xlsx')  # 假设所有文件都以"销售数据_"开头
# 2. 读取并合并所有文件
all_data = pd.DataFrame()
for file in file_paths:
    df = pd.read_excel(file)
    all_data = pd.concat([all_data, df], ignore_index=True)
# (可选) 如果文件名包含月份信息,可以提取出来作为新列
# all_data['月份'] = all_data['文件名'].apply(lambda x: x.split('_')[1])
# 3. 生成数据透视表
pivot_table = pd.pivot_table(all_data,
                             values='销售额',
                             index='地区',
                             columns='产品',
                             aggfunc='sum',
                             margins=True,
                             margins_name='总计',
                             fill_value=0)
# 4. 导出结果
pivot_table.to_excel('汇总透视表.xlsx')
print("透视表已生成!")

这类做法的重点有两个:一是所有源文件字段结构必须一致;二是如果文件名本身携带月份、门店等信息,可以额外提取成新列,后面就能直接加入透视维度。

场景二:把一个工作簿里的多个 Sheet 合并后再透视

另一种常见情况,是一年 12 个月的数据都放在同一个 Excel 工作簿里,只是分散在不同 Sheet。这里可以用 sheet_name=None 一次性读入全部工作表。

import pandas as pd
# 1. 读取所有Sheet,sheet_name=None会返回一个字典
all_sheets = pd.read_excel('全年销售数据.xlsx', sheet_name=None)
# 2. 合并所有Sheet,并添加来源Sheet名作为新列
all_data = pd.DataFrame()
for sheet_name, df in all_sheets.items():
    df['月份'] = sheet_name  # 新增一列标记数据来源
    all_data = pd.concat([all_data, df], ignore_index=True)
# 3. 生成透视表(按月份和地区汇总)
pivot_table = pd.pivot_table(all_data,
                             values='销售额',
                             index=['月份', '地区'],
                             columns='产品',
                             aggfunc='sum',
                             fill_value=0,
                             margins=True,
                             margins_name='总计')
# 4. 导出结果
pivot_table.to_excel('月度销售透视表.xlsx')

这里 pd.read_excel(..., sheet_name=None) 返回的是一个字典,键是 Sheet 名,值是对应的 DataFrame。把 Sheet 名顺手写入新列“月份”后,后续透视时就能直接按月份、地区一起汇总。

场景三:从同一份源数据生成多个透视表并写入一个 Excel

如果你的需求不是做一张透视表,而是想同时得到“按地区汇总”“按产品汇总”“地区 × 产品交叉汇总”,可以用 pd.ExcelWriter 把多个结果写到同一个工作簿的不同 Sheet 中。

import pandas as pd
df = pd.read_excel('源数据.xlsx')
with pd.ExcelWriter('多维度透视报告.xlsx', engine='openpyxl') as writer:
    # 1. 按地区汇总
    pivot1 = pd.pivot_table(df, values='销售额', index='地区',
                            aggfunc='sum', margins=True, margins_name='合计')
    pivot1.to_excel(writer, sheet_name='地区汇总')
    # 2. 按产品汇总
    pivot2 = pd.pivot_table(df, values='销售额', index='产品',
                            aggfunc='sum', margins=True, margins_name='合计')
    pivot2.to_excel(writer, sheet_name='产品汇总')
    # 3. 地区 × 产品 交叉透视
    pivot3 = pd.pivot_table(df, values='销售额', index='地区', columns='产品',
                            aggfunc='sum', fill_value=0, margins=True, margins_name='合计')
    pivot3.to_excel(writer, sheet_name='地区_产品交叉')

这种方式的优点很明确:一次运行,直接得到多张报表,适合定期生成对比分析文件。

场景四:在原有 Excel 工作簿里回写透视结果

有些团队并不满足于“生成一个新结果文件”,而是希望直接打开现有工作簿、遍历其中所有 Sheet,再把每个 Sheet 的透视结果写回同一个工作簿。这时可以考虑 xlwings。

需要注意,原文明确说明这种方式依赖本地安装 Excel,运行时也会调用本机 Excel 应用程序。

import pandas as pd
import xlwings as xw
def batch_pivot_in_workbook(input_xlsx, index_col, value_col, columns_col=None, aggfunc='sum'):
    """遍历Excel中的所有工作表,生成透视表并写入新sheet"""
    app = xw.App(visible=False)
    wb = app.books.open(input_xlsx)
    summary_sheet = wb.sheets.add('透视汇总')
    row_offset = 0
    for sheet in wb.sheets:
        if sheet.name == '透视汇总':
            continue
        # 读取数据
        data_range = sheet.range('A1').expand('table')
        df = data_range.options(pd.DataFrame, header=1).value
        # 清洗数值列(去除货币符号等)
        df[value_col] = df[value_col].astype(str).str.replace(r'[¥¥$,]', '', regex=True)
        df[value_col] = pd.to_numeric(df[value_col], errors='coerce').fillna(0)
        # 生成透视表
        pivot = pd.pivot_table(df,
                               index=index_col,
                               columns=columns_col if columns_col else None,
                               values=value_col,
                               aggfunc=aggfunc,
                               fill_value=0,
                               margins=True,
                               margins_name='总计')
        # 将透视表写入汇总sheet
        summary_sheet.range(row_offset + 1, 1).value = f'--- {sheet.name} 的透视结果 ---'
        summary_sheet.range(row_offset + 2, 1).value = pivot
        row_offset += len(pivot) + 4  # 为下一个透视表留出空行
    wb.sa ve()
    wb.close()
    app.quit()
    print(f"批量透视完成,结果已写入 '透视汇总' sheet。")
# 调用函数
batch_pivot_in_workbook('数据文件.xlsx', index_col='地区', value_col='销售额', columns_col='产品')

这段代码的核心价值,不是单纯做汇总,而是把“读取原表、清洗数值、生成透视、写回工作簿”连成一个完整流程。对于仍然强依赖 Excel 交互环境的团队,这会比单独导出结果文件更贴近现有习惯。

什么时候只用 pandas,什么时候再加 xlwings

从本文几个示例可以看出,pivot_table 始终是中心能力,真正的差别在于数据从哪里来、结果要写到哪里去。

展示 pandas 导出多张透视表与 xlwings 回写原工作簿两种方案对比的白底信息图
pandas 与 xlwings 的使用边界用对比图区分“生成新报表”和“操作原工作簿”两种路线,帮助读者按场景选工具。
  • 如果只是读取数据、计算结果、导出新的 .xlsx 报表,用 pandas + openpyxl 通常已经足够。
  • 如果需要直接操作现有 Excel 工作簿,并把结果回写到原文件中,可以考虑 xlwings。

可以把这类批量任务概括成一个固定套路:先读取,再合并,再透视,最后导出。只要源数据字段结构稳定,很多原本需要反复手工点选的 Excel 工作,最后都能收敛成一段可以重复执行的 Python 脚本。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表