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

如何快速读取Zip压缩包内Excel文件并高效完成读写操作?

压缩包内Excel读写性能优化方案

针对你这段循环处理压缩包内Excel并写入结果的代码,以下是几个直击性能瓶颈的优化方案:

1. 避免重复解析同一个Excel文件

原代码中对同一个压缩包内的Excel文件调用两次pd.read_excel(分别读取Sheet1和Sheet2),这会导致文件被重复解析两次,浪费IO和计算资源。改用pd.ExcelFile一次性加载文件,再读取多个Sheet,能直接减少一半的文件解析开销:

# 优化后:一次性加载Excel文件,再读取多个Sheet
with pd.ExcelFile(xlfile_pro) as xls_pro:
    sheet1_pro = pd.read_excel(xls_pro, sheet_name='Sheet1')
    sheet2_pro = pd.read_excel(xls_pro, sheet_name='Sheet2')

with pd.ExcelFile(xlfile_ref) as xls_ref:
    sheet1_ref = pd.read_excel(xls_ref, sheet_name='Sheet1')
    sheet2_ref = pd.read_excel(xls_ref, sheet_name='sheet2')

2. 只读取需要的目标行,拒绝全量加载

你只需要计算特定行(Row1、Row29)的求和值,完全没必要加载整个Sheet的所有数据。通过精准定位目标行并只读取这些行,能大幅减少内存占用和读取时间:

如果目标行是按行名(index label)定位

def get_target_row(xls_file, sheet_name, target_row_label):
    # 先读取行索引,定位目标行的位置
    df_index = pd.read_excel(xls_file, sheet_name=sheet_name, usecols=[0], index_col=0)
    target_row_pos = df_index.index.get_loc(target_row_label) + 2  # 转换为Excel行号(从1开始)
    # 只读取目标行
    return pd.read_excel(xls_file, sheet_name=sheet_name, skiprows=target_row_pos-1, nrows=1, index_col=0)

# 使用示例
with pd.ExcelFile(xlfile_pro) as xls_pro:
    sheet2_row1 = get_target_row(xls_pro, 'Sheet2', 'Row 1')
    sheet1_row29 = get_target_row(xls_pro, 'Sheet1', 'Row29')

with pd.ExcelFile(xlfile_ref) as xls_ref:
    sheet2_ref_row1 = get_target_row(xls_ref, 'Sheet2', 'Row 1')
    sheet1_ref_row29 = get_target_row(xls_ref, 'Sheet1', 'Row29')

# 计算逻辑不变
x = (sheet2_row1.sum().iloc[0] - sheet2_ref_row1.sum().iloc[0]) * -1
y = (sheet1_row29.sum().iloc[0] - sheet1_ref_row29.sum().iloc[0]) * 0.7 / 1000 * -1

如果目标行是按行号(比如第1行、第29行)

直接跳过无关行,只读取目标行:

def get_row_by_number(xls_file, sheet_name, row_num):
    # row_num为Excel中的行号(从1开始)
    return pd.read_excel(xls_file, sheet_name=sheet_name, skiprows=row_num-1, nrows=1, index_col=0)

3. 批量写入结果,避免频繁文件IO

原代码每次循环都打开、修改、保存Excel文件,这是最大的性能杀手之一。应该先把所有循环的计算结果收集到一个DataFrame中,最后一次性写入文件,把多次IO操作减少为一次:

# 提前初始化结果DataFrame(根据你的需求定义结构)
df_results = pd.DataFrame(index=['Specific Row'], columns=[f'Col{i}' for i in range(4)])

with ZipFile(Project_path) as zip_file_pro , ZipFile(Reference_path) as zip_file_ref:
    for fn_pro,(member_pro , member_ref) in enumerate(zip(zip_file_pro.namelist(),zip_file_ref.namelist())):
        # ... 前面的读取和计算逻辑 ...
        # 将当前循环的结果存入df_results
        df_results.loc['Specific Row', df_results.columns[3]] = (x - y) * 1

# 循环结束后,一次性写入Excel
project_exl = load_workbook(file_path)
with pd.ExcelWriter(file_path, engine='openpyxl') as Write_result:
    Write_result.book = project_exl
    Write_result.sheets = {ws.title: ws for ws in project_exl.worksheets}
    df_results.to_excel(Write_result, sheet_name='Result_1', index=False, header=False, startrow=12, startcol=3)
# 使用with上下文管理器会自动关闭并保存,无需手动调用close()和save()

4. 更换更高效的Excel引擎

Pandas的read_excel支持多种引擎,针对.xlsx文件,pyxlsb(处理二进制格式xlsx)的读取速度比默认的openpyxl快很多。先安装依赖:

pip install pyxlsb

然后在读取时指定引擎:

sheet1_pro = pd.read_excel(xls_pro, sheet_name='Sheet1', engine='pyxlsb')

5. 并行处理(适合大量Excel文件的场景)

如果压缩包内有几十上百个Excel文件,可以用多线程并行处理,利用CPU多核提升效率:

from concurrent.futures import ThreadPoolExecutor

def process_single_pair(member_pro, member_ref):
    # 每个线程单独打开Zip文件(避免线程安全问题)
    with ZipFile(Project_path) as zip_file_pro, ZipFile(Reference_path) as zip_file_ref:
        xlfile_pro = zip_file_pro.open(member_pro)
        xlfile_ref = zip_file_ref.open(member_ref)
        # ... 读取目标行、计算逻辑 ...
        return (x - y) * 1

# 获取两个压缩包的成员列表
with ZipFile(Project_path) as zip_file_pro, ZipFile(Reference_path) as zip_file_ref:
    members_pro = zip_file_pro.namelist()
    members_ref = zip_file_ref.namelist()

# 并行处理,max_workers根据CPU核心数调整
with ThreadPoolExecutor(max_workers=4) as executor:
    all_results = list(executor.map(process_single_pair, members_pro, members_ref))

# 将结果批量填充到df_results中
df_results.loc['Specific Row', df_results.columns[3]] = all_results[-1]  # 根据你的需求调整赋值逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:15:40