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

如何优化Python编写的Excel指定行跨表迁移脚本运行效率

问题背景

正在开发Excel自动化处理程序,核心需求为检测Excel文件的指定列,将指定列为空的对应行移动到同一工作簿的Linkedin Only工作表中。目前基于openpyxl编写的初版代码运行效率较低,需要基于pandas或其他工具库实现更高性能的方案。
初版openpyxl实现代码如下:

import time
start_time = time.perf_counter ()
import openpyxl
wb = openpyxl.load_workbook("Test.xlsx")
ws=wb.active
mr,mc=ws.max_row,ws.max_column
column_string=input("Enter Column Letter with Email (A or B or C or leave blank to skip editing):").upper()
if len(column_string)>0:
    for cell in ws[column_string][1:]:
        if cell.value is None:
            ws_1=wb.create_sheet('Linkedin Only')
            for i in range (1, mr +1):
                for j in range (1, mc + 1):
                    c = ws.cell(row = i, column = j)
                    ws_1.cell(row = i, column = j).value = c.value
            break
    for cell in ws_1[column_string][1:]:
        if cell.value is not None:
            ws_1.delete_rows(cell.row)
    for cell in ws[column_string][1:]:
        if cell.value is None:
            ws.delete_rows(cell.row)
    wb.save("Test.xlsx")
else:
    wb.save("Test.xlsx")
end_time = time.perf_counter ()
print(end_time - start_time, "seconds")
初版代码性能瓶颈
  • 全表数据复制用了逐行逐单元格的双层循环,openpyxl单单元格读写的IO开销极高,数据量过万时耗时会陡增
  • 行删除操作逐行触发delete_rows,每次删除都会重算整个工作表的行索引,不仅速度慢,还容易因为行号偏移出现漏删、错删的问题
  • 对同一列做了3次全量遍历,存在大量冗余操作
高性能实现方案

根据是否需要保留原Excel的格式样式,可选择以下两种方案:

方案1:pandas批量处理(性能最优,适合无复杂格式的纯数据表格)

pandas基于数组做批量运算和读写,没有逐单元格操作的开销,万行级数据处理速度比初版openpyxl代码快50~200倍。
实现代码:

import time
import pandas as pd
from openpyxl import load_workbook

start_time = time.perf_counter()
file_path = "Test.xlsx"
column_string = input("Enter Column Letter with Email (A or B or C or leave blank to skip editing):").upper()

if len(column_string) > 0:
    # 读取活动工作表全量数据
    active_ws_name = load_workbook(file_path, read_only=True).active.title
    df = pd.read_excel(file_path, sheet_name=active_ws_name, engine='openpyxl')
    # 列字母转pandas列索引(A对应0,B对应1以此类推)
    col_idx = ord(column_string) - ord('A')
    target_col = df.columns[col_idx]
    
    # 一次性拆分两组数据:原表保留非空行,新表存空值行
    df_keep = df[df[target_col].notna()]
    df_move = df[df[target_col].isna()]

    # 写回文件,保留原工作簿其他工作表
    with pd.ExcelWriter(
        file_path,
        engine='openpyxl',
        mode='a',
        if_sheet_exists='replace'
    ) as writer:
        df_keep.to_excel(writer, sheet_name=active_ws_name, index=False)
        df_move.to_excel(writer, sheet_name='Linkedin Only', index=False)

end_time = time.perf_counter()
print(end_time - start_time, "seconds")

注意:如果原工作表有复杂公式、合并单元格、自定义样式,不要用这个方案,pandas写入时会丢失这些格式。

方案2:优化版openpyxl实现(保留原格式,性能比初版高10~30倍)

核心优化点是取消逐单元格复制、逐行删除的逻辑,一次性把所有行读入内存筛选,再批量写回工作表,避免重复IO和行号重算开销。
实现代码:

import time
from openpyxl import load_workbook

start_time = time.perf_counter()
wb = load_workbook("Test.xlsx")
ws = wb.active
mr, mc = ws.max_row, ws.max_column
column_string = input("Enter Column Letter with Email (A or B or C or leave blank to skip editing):").upper()

if len(column_string) > 0:
    # 一次性读入表头和所有行数据
    header = [cell.value for cell in ws[1]]
    all_rows = list(ws.iter_rows(min_row=2, max_row=mr, max_col=mc, values_only=True))
    col_idx = ord(column_string) - ord('A')
    
    # 一次性拆分数据
    keep_rows = []
    move_rows = []
    for row in all_rows:
        if row[col_idx] is None:
            move_rows.append(row)
        else:
            keep_rows.append(row)
    
    # 删除原表旧数据
    if mr > 1:
        ws.delete_rows(2, mr-1)
    # 创建/重置目标工作表
    if 'Linkedin Only' in wb.sheetnames:
        del wb['Linkedin Only']
    ws_1 = wb.create_sheet('Linkedin Only')
    
    # 批量写回两个工作表
    ws.append(header)
    for row in keep_rows:
        ws.append(row)
    
    ws_1.append(header)
    for row in move_rows:
        ws_1.append(row)

wb.save("Test.xlsx")
end_time = time.perf_counter()
print(end_time - start_time, "seconds")
方案选择建议
  • 处理的是纯数据导出的表格,不需要保留样式、公式,优先选pandas方案,处理速度最快
  • 需要保留原表的样式、公式、合并单元格等格式,选优化版openpyxl方案,兼容性更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:06:27