使用Openpyxl与Pandas处理87MB Excel文件操作耗时过长求助
优化大Excel数据处理方案(解决慢+支持同时读写+无需保留xlsx)
核心思路
放弃直接操作.xlsx格式,转用列式存储格式(如Parquet)或内存友好的文本格式(如CSV)——这类格式读写速度远快于xlsx,且原生支持并行操作;同时结合Pandas优化方法或Dask框架,实现高效的同时读写与计算。
具体实现步骤
1. 一次性将Excel转成高效格式(仅需执行一次)
把原87MB的Excel转成Parquet(比CSV更快,还能保留数据类型),后续所有操作都基于这个文件:
import pandas as pd book = 'file path' sheet_names = ['1', '2'] # 替换为你需要的所有工作表名 dfs = pd.read_excel(book, sheet_name=sheet_names) # 按工作表拆分保存为Parquet for sheet_name, df in dfs.items(): df.to_parquet(f'{sheet_name}.parquet')
2. 高效处理数据(支持同时读写+快速计算)
方案A:Pandas优化操作(适合单机器内存充足)
Parquet支持多线程快速读写,可边读边处理,同时写入结果:
import pandas as pd # 并行读取Parquet文件 df1 = pd.read_parquet('1.parquet') df2 = pd.read_parquet('2.parquet') # 维度检查(保留原逻辑) if df1.shape != df2.shape: raise ValueError("Sheets have different shapes") # 删除无用行列 df1 = df1.drop(columns=['冗余列1', '冗余列2']).dropna(axis=0, subset=['核心列']) df2 = df2.drop(columns=['冗余列1', '冗余列2']).dropna(axis=0, subset=['核心列']) # 计算均值并保存 mean_result = df1.mean(numeric_only=True).to_frame(name='均值') mean_result.to_parquet('均值结果.parquet') # 跨表单元格相乘并保存 cross_multiply_result = df1 * df2 cross_multiply_result.to_parquet('跨表相乘结果.parquet')
方案B:Dask并行处理(适合内存不足或超大数据)
Dask会自动将数据分块,并行执行读写与计算,避免内存溢出:
import dask.dataframe as dd # 分块读取Parquet ddf1 = dd.read_parquet('1.parquet') ddf2 = dd.read_parquet('2.parquet') # 维度检查(需先计算实际shape) if ddf1.shape.compute() != ddf2.shape.compute(): raise ValueError("Sheets have different shapes") # 删除无用行列 ddf1 = ddf1.drop(columns=['冗余列1', '冗余列2']).dropna(axis=0, subset=['核心列']) ddf2 = ddf2.drop(columns=['冗余列1', '冗余列2']).dropna(axis=0, subset=['核心列']) # 计算均值并保存 mean_result = ddf1.mean(numeric_only=True).compute().to_frame(name='均值') mean_result.to_parquet('均值结果.parquet') # 跨表相乘并行写入结果 cross_multiply_result = ddf1 * ddf2 cross_multiply_result.to_parquet('跨表相乘结果.parquet', write_index=False)
3. 方案优势说明
- 读写速度飙升:Parquet是列式存储,读写速度比xlsx快10-100倍,且支持压缩,文件体积更小
- 原生支持同时读写:Parquet兼容多线程/并行读写,Pandas和Dask均可在读取过程中同步计算,也能边计算边写入结果
- 完全脱离xlsx依赖:全程用Parquet/CSV处理,最终结果也存为这类格式,无需保留任何xlsx文件
额外提速技巧
- 首次读取Excel时,用
usecols参数只加载需要的列,减少内存占用和读取时间:pd.read_excel(book, sheet_name=sheet1, usecols=['列1', '列2']) - 计算均值时指定
numeric_only=True,跳过非数值列提升效率 - 若选择CSV格式,可使用
pd.read_csv的chunksize参数分块处理,适配内存较小的机器
内容的提问来源于stack exchange,提问作者Leafy
相关产品推荐
相关产品推荐

