如何用Python快速读取ZIP压缩大型CSV贸易数据并合并提取指定国家数据
优化方案
你的代码速度极慢的核心原因是:每次都先把全年5GB+的全量数据完整加载到内存后才做筛选,32年数据同时驻留内存会触发频繁的内存交换,耗时自然会大幅拉长。优化方向围绕减少不必要的数据加载+批量循环处理展开:
核心优化点
- 读数据块时直接过滤,不需要加载全量年度数据到内存
- 仅读取你实际需要的列,跳过无用列大幅减少IO耗时
- 用循环批量处理所有年份文件,避免重复冗余代码
- 预先指定列的数据类型,减少pandas自动类型推断的耗时
优化后可直接运行的代码
import pandas as pd # 配置参数 reporter = 'Egypt' start_year = 1989 end_year = 2020 # 按需修改为你实际需要保留的列,不要保留无用列,能大幅提升读取速度 needed_cols = ['Reporter', 'Partner', 'Trade Flow', 'Year', 'Value', 'Commodity'] res_list = [] # 循环处理所有年份 for year in range(end_year, start_year-1, -1): filename = f"All {year}.zip" print(f"正在处理{year}年数据...") chunk_list = [] # 按块读取+即时过滤 for chunk in pd.read_csv( filename, chunksize=100000, # 可根据内存大小调整,10万行比1万行处理效率更高 usecols=needed_cols, engine='c', dtype={'Year': int, 'Value': float} # 预先指定列类型,省去自动推断耗时 ): filtered_chunk = chunk[chunk['Reporter'] == reporter] if not filtered_chunk.empty: chunk_list.append(filtered_chunk) # 合并当前年度的筛选结果加入总列表 if chunk_list: year_df = pd.concat(chunk_list, ignore_index=True) res_list.append(year_df) # 合并所有年度数据得到最终结果 final_df = pd.concat(res_list, ignore_index=True) # 建议后续存储为parquet格式,比csv占用空间小、读写速度快数倍 # final_df.to_parquet('egypt_trade_1989_2020.parquet', index=False)
进阶提速方案
如果上述方案仍无法满足速度要求,可以换用polars库处理,它是基于Rust开发的高性能数据处理库,处理大文件速度比pandas高3-10倍,无需手动处理chunk,代码更简洁:
import polars as pl reporter = 'Egypt' start_year = 1989 end_year = 2020 needed_cols = ['Reporter', 'Partner', 'Trade Flow', 'Year', 'Value', 'Commodity'] df_list = [] for year in range(end_year, start_year-1, -1): df = pl.read_csv( f"All {year}.zip", columns=needed_cols ).filter(pl.col('Reporter') == reporter) df_list.append(df) final_df = pl.concat(df_list) # 如需转pandas格式,调用final_df.to_pandas()即可
内容的提问来源于stack exchange,提问作者Fatima El Mansouri
相关产品推荐
相关产品推荐

