相同代码在Jupyter正常运行,命令行Python触发MemoryError
解决读取CSV时命令行出现MemoryError的问题
首先得说,Jupyter Notebook和命令行Python的内存管理逻辑确实有差异——Jupyter可能在内存回收上更灵活,或者你没注意到它其实也在悄悄占用更多内存但没触发报错。不过核心问题还是一次性读取9个CSV文件的内存开销超出了命令行Python进程的承载能力,咱们可以从优化读取逻辑和内存管理入手解决:
1. 优先精简加载内容
如果你的代码不需要用到CSV里的所有列,直接用usecols指定要加载的列,这是最立竿见影的内存节省手段:
df1 = pd.read_csv("../Data/1.csv", usecols=["必需列1", "必需列2"])
2. 手动指定数据类型
Pandas自动推断数据类型时,经常会把小数值列推断成大类型(比如把int默认设为int64),或者把重复率极高的字符串列设为object类型。手动指定dtype能大幅压缩内存:
# 整数列用更小的类型,重复多的字符串列用category df2 = pd.read_csv('../Data/2.csv', index_col=0, dtype={ "数值列": "int32", "重复字符串列": "category" })
3. 分块读取超大文件
如果单个CSV文件特别大,没法一次性加载,就用chunksize分块读取,处理完一块再合并(如果需要完整DataFrame的话):
# 每次读取10000行 chunk_iter = pd.read_csv("../Data/1.csv", chunksize=10000) df_list = [] for chunk in chunk_iter: # 这里可以先对chunk做预处理(过滤、计算等),减少后续内存占用 df_list.append(chunk) df1 = pd.concat(df_list, ignore_index=True)
4. 手动触发内存回收
命令行Python的垃圾回收可能不如Jupyter及时,你可以在读取过程中手动调用垃圾回收,释放临时占用的内存:
import gc def read_matrixs(): import pandas as pd df1 = pd.read_csv("../Data/1.csv") # 读取完一个文件后就回收一次 gc.collect() df2 = pd.read_csv('../Data/2.csv', index_col=0) gc.collect() # ... 读取其他文件 ... return df1, df2, ...
5. 检查Python环境位数
如果你的命令行用的是32位Python,内存上限只有4GB左右,很容易触发MemoryError。你可以在命令行运行以下代码确认:
python -c "import sys; print('64位' if sys.maxsize > 2**32 else '32位')"
如果是32位,换成64位Python就能解决大部分内存限制问题。
额外小技巧:提前预估内存占用
读取前可以先估算每个CSV加载后的内存,心里有数:
import pandas as pd def estimate_csv_memory(file_path): # 读前100行推断类型 sample = pd.read_csv(file_path, nrows=100) # 计算单样本内存,预估整体内存 sample_mem = sample.memory_usage(deep=True).sum() total_rows = sum(1 for _ in open(file_path)) - 1 # 减去表头行 estimated_mem = (sample_mem / 100) * total_rows print(f"{file_path} 预估内存: {estimated_mem / 1024 / 1024:.2f} MB")
内容的提问来源于stack exchange,提问作者Harold
相关产品推荐
相关产品推荐

