32位Anaconda环境Python2转Python3时pandas.read_csv遇MemoryError求助
嘿,我完全懂你现在的糟心处境——在32位Anaconda环境里升级到Python3,读个300MB的CSV直接爆MemoryError,就算砍到50MB还是不行,还不想用chunksize拆成块,就想要完整的DataFrame对吧?下面给你几个针对性的解决办法,亲测在32位环境里管用:
解决32位Anaconda读取大CSV的内存瓶颈
1. 给pd.read_csv加内存优化参数,从源头减少占用
Pandas默认的类型推断会把数据存成更耗内存的格式,我们手动干预能大幅压缩内存:
- 指定列的
dtype:把整数列设为int32(而非默认int64)、浮点列设为float32,字符串列如果是有限的类别(比如状态码、分类标签)改成category类型。示例:
# 先分析你的列类型,再针对性指定 dtype_config = { "user_id": "int32", "status": "category", "amount": "float32" } e1 = pd.read_csv(working_dir+"E1.txt", sep=',', dtype=dtype_config)
- 用
usecols只读需要的列:如果你的代码不需要CSV里的所有列,直接指定要加载的列,能瞬间砍掉多余内存占用:
e1 = pd.read_csv(working_dir+"E1.txt", sep=',', usecols=["user_id", "amount", "create_time"])
- 启用
low_memory=False:这个参数会让Pandas一次性推断整列的类型,避免分块推断导致的类型冗余,也能减少内存波动(如果列类型混杂会有警告,但数据规范的话很有用)。
2. 开启memory_map映射文件到内存
这个参数会把CSV文件直接映射到内存,而不是一次性加载到RAM里,对32位环境的内存压力缓解很明显,用法超简单:
e1 = pd.read_csv(working_dir+"E1.txt", sep=',', memory_map=True)
3. 转存为高效二进制格式(一劳永逸)
如果需要反复读取这个文件,先把CSV转成Parquet或Feather格式——这些格式不仅读取速度快,内存占用只有CSV的几分之一:
如果能勉强读一次文件(或者用chunksize分块合并),就转存:
# 先读取(用上面的优化参数) e1 = pd.read_csv(working_dir+"E1.txt", sep=',', dtype=dtype_config) # 转存为Parquet e1.to_parquet(working_dir+"E1.parquet") # 之后读取直接用: e1 = pd.read_parquet(working_dir+"E1.parquet")
如果一次读取都失败,就分块读取后合并再转存:
chunk_list = [] # 分块读取,每块10000行(可根据内存调整) for chunk in pd.read_csv(working_dir+"E1.txt", sep=',', chunksize=10000, dtype=dtype_config): chunk_list.append(chunk) # 合并成完整DataFrame e1 = pd.concat(chunk_list) # 转存 e1.to_parquet(working_dir+"E1.parquet")
之后再读这个Parquet文件,内存压力会小很多,而且支持列存储,读取指定列更高效。
4. 读取前清理环境内存
有时候不是文件太大,而是当前环境里有其他闲置变量占着内存,读取前手动清理一下:
import gc # 清理未被引用的变量,释放内存 gc.collect() # 再执行读取操作 e1 = pd.read_csv(working_dir+"E1.txt", sep=',', dtype=dtype_config)
补充:为什么32位环境这么容易爆内存?
32位Python进程的内存上限通常在2GB左右,而Pandas把CSV转成DataFrame时,内存占用会是原始文件的2-5倍(比如文本格式的数字存成float64,内存会膨胀很多),所以300MB的CSV转成DataFrame很容易突破2GB上限,就算50MB的CSV如果没优化类型也可能触发MemoryError。
内容的提问来源于stack exchange,提问作者excelguy
相关产品推荐
相关产品推荐

