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

如何高效将pandas dataframe按内置文件名、工作表名导出为多Sheet Excel

pandas批量导出多文件多工作表的高效实现方案

需求说明

从pandas DataFrame批量生成导出文件,文件名、工作表名称均存储在原始数据中,支持生成多个导出文件,每个文件可包含多张工作表。

示例数据

示例数据

现有实现的可优化点

  • 变量重名:内层循环复用外层grouped、name等变量,易引发逻辑异常
  • CSV导出逻辑错误:错误将ExcelWriter对象传入to_csv方法,无法正常生成CSV文件
  • 终止逻辑不合理:单个文件命名非法就终止所有导出任务,不符合多文件导出预期
  • 未兼容CSV多工作表场景:CSV不支持多工作表,同名CSV下的多个工作表会出现数据覆盖
  • 重复计算:循环内重复执行列删除操作,可提前统一处理

优化实现

首先明确:分组导出的核心逻辑无法完全规避遍历分组,但可以通过优化计算逻辑、并行IO的方式大幅提升执行效率,尤其适合文件量较大的场景。

1. 优化串行版(无额外依赖,修正所有问题,执行效率高于原有实现)

import pandas as pd
from pathlib import Path

# 提前提取非分组列,避免循环内重复drop
value_cols = [col for col in data.columns if col not in ["Filename", "Sheetname"]]
# 按文件名分组
file_groups = data.groupby("Filename", as_index=False)

for filename, file_df in file_groups:
    # 校验文件格式
    suffix = Path(filename).suffix.lower()
    if suffix not in (".xlsx", ".csv"):
        print(f"跳过无效文件:{filename},仅支持xlsx和csv格式")
        continue
    
    # 按工作表名分组
    sheet_groups = file_df.groupby("Sheetname", as_index=False)
    if suffix == ".xlsx":
        # 同一个Excel写入多个工作表
        with pd.ExcelWriter(filename, engine="openpyxl") as writer:
            for sheet_name, sheet_df in sheet_groups:
                sheet_df[value_cols].to_excel(writer, sheet_name=sheet_name, index=False)
    else:
        # CSV不支持多工作表,每个工作表单独生成文件
        for sheet_name, sheet_df in sheet_groups:
            # 多工作表时给CSV文件名加工作表后缀避免覆盖
            csv_filename = f"{Path(filename).stem}_{sheet_name}{suffix}" if len(sheet_groups) > 1 else filename
            sheet_df[value_cols].to_csv(csv_filename, index=False)

2. 并行加速版(适合文件数≥10的场景,IO密集型场景效率可提升3~10倍)

利用多线程并行处理不同文件的导出任务,充分利用IO等待时间:

import pandas as pd
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed

# 提前提取非分组列
value_cols = [col for col in data.columns if col not in ["Filename", "Sheetname"]]
file_groups = data.groupby("Filename", as_index=False)

def export_single_file(filename, file_df):
    suffix = Path(filename).suffix.lower()
    if suffix not in (".xlsx", ".csv"):
        return f"跳过无效文件:{filename}"
    
    sheet_groups = file_df.groupby("Sheetname", as_index=False)
    if suffix == ".xlsx":
        with pd.ExcelWriter(filename, engine="openpyxl") as writer:
            for sheet_name, sheet_df in sheet_groups:
                sheet_df[value_cols].to_excel(writer, sheet_name=sheet_name, index=False)
    else:
        for sheet_name, sheet_df in sheet_groups:
            csv_filename = f"{Path(filename).stem}_{sheet_name}{suffix}" if len(sheet_groups) > 1 else filename
            sheet_df[value_cols].to_csv(csv_filename, index=False)
    return f"导出完成:{filename}"

# 最大线程数可根据实际情况调整,一般设置为5~20即可
with ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(export_single_file, fname, f_df) for fname, f_df in file_groups]
    for future in as_completed(futures):
        print(future.result())

优化说明

  • 提前统一计算需要保留的列,避免循环内重复执行drop操作,减少冗余计算
  • 用上下文管理器with处理文件写入对象,自动管理资源,无需手动调用save
  • 修正CSV导出逻辑,兼容多工作表场景,避免数据覆盖
  • 单个文件导出失败不会影响其他文件,错误提示更清晰
  • 并行版利用IO等待时间同时处理多个文件,文件量越大提升效果越明显

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:06:04