如何用Pandas读取多个大型CSV文件?解决内存报错问题
问题分析与解决方案
先修正代码中的逻辑错误
你的代码存在三个明显问题,直接导致功能失效:
- 循环内始终读取
file_list[1],应该改用file_list[i]遍历所有文件 - 使用
axis=1进行列方向拼接,这会把所有文件的列堆叠在一起,不符合合并多行数据的需求,应改为axis=0 - 拼接结果存入
main_dataframe但未更新main_df,最后打印的始终是第一个文件的数据
修正后的基础代码(仍会存在内存问题):
import glob import pandas as pd folder_path = 'train/operations-data' file_list = glob.glob(folder_path + "/*.csv") main_df = pd.read_csv(file_list[0]) for i in range(1, len(file_list)): df = pd.read_csv(file_list[i]) main_df = pd.concat([main_df, df], axis=0) print(main_df)
解决内存错误的核心方案
1. 分块读取文件
利用read_csv的chunksize参数,将每个文件拆分成小批次读取,逐块合并结果,避免一次性加载全部数据到内存:
import glob import pandas as pd folder_path = 'train/operations-data' file_list = glob.glob(folder_path + "/*.csv") main_df = pd.DataFrame() for file in file_list: # 每批次读取10000行,可根据内存情况调整 chunk_iter = pd.read_csv(file, chunksize=10000) for chunk in chunk_iter: main_df = pd.concat([main_df, chunk], axis=0) # 重置索引(可选,避免索引重复) main_df = main_df.reset_index(drop=True)
2. 指定数据类型压缩内存
Pandas默认会给列分配冗余的数据类型(比如把小范围整数存为int64),手动指定更合适的类型能大幅降低内存占用:
# 先读取小样本分析列的数据范围 sample_df = pd.read_csv(file_list[0], nrows=1000) # 根据样本定义类型映射,示例如下 dtype_dict = { 'small_int_col': 'int32', 'low_precision_float': 'float32', 'high_repeat_str_col': 'category' # 重复值多的字符串列用category类型 } main_df = pd.DataFrame() for file in file_list: chunk_iter = pd.read_csv(file, chunksize=10000, dtype=dtype_dict) for chunk in chunk_iter: main_df = pd.concat([main_df, chunk], axis=0)
3. 只读取需要的列
如果不需要所有字段,用usecols参数指定要加载的列,直接减少内存开销:
cols_to_keep = ['col1', 'col2', 'col3'] # 替换为你需要的列名 main_df = pd.DataFrame() for file in file_list: chunk_iter = pd.read_csv(file, chunksize=10000, usecols=cols_to_keep) for chunk in chunk_iter: main_df = pd.concat([main_df, chunk], axis=0)
4. 用Dask处理超大数据集
如果以上方法仍无法解决,可使用Dask库——它专门处理超出内存的数据集,用法和Pandas高度兼容:
import dask.dataframe as dd import glob folder_path = 'train/operations-data' file_list = glob.glob(folder_path + "/*.csv") # 读取所有CSV文件,不加载到内存 dask_df = dd.read_csv(file_list) # 如需转为Pandas DataFrame(内存足够时),或直接用Dask进行计算 main_df = dask_df.compute()
内容的提问来源于stack exchange,提问作者suri
相关产品推荐
相关产品推荐

