如何在python中循环遍历大型数据集而不获取MemoryError?

2024-05-13 09:28:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一大系列的栅格数据集,代表了几十年来的月降雨量。我用Python编写了一个脚本,它在每个光栅上循环,并执行以下操作:

  1. 将光栅转换为numpy蒙面数组
  2. 执行大量的数组代数来计算新的水位
  3. 将结果写入输出光栅。
  4. 重复

脚本只是一个由循环语句括起来的数组代数方程的长列表。

如果我只是在我的一小部分数据上运行脚本(比如说20年),一切都会很好,但是如果我尝试处理所有数据,我会得到一个MemoryError。这个错误没有提供更多的信息(除了它突出显示了Python放弃的代码行)。

不幸的是,我不能很容易地把我的数据分块处理——我真的需要能够同时处理所有的事情。这是因为,在每次迭代结束时,输出(水位)作为起点反馈到下一次迭代中。

目前我对编程的理解是非常基础的,但是我认为我的所有对象都会被每个循环覆盖。我(傻了?)假设如果代码成功循环一次,那么它应该能够无限循环,而不会占用越来越多的内存。

我试过阅读各种各样的文件,发现了一种叫做“垃圾收集器”的东西,但我觉得我已经超出了我的深度,我的大脑正在融化!有谁能提供一些基本的洞察,当我的代码循环时,内存中的对象实际发生了什么?在每个循环的末尾是否有释放内存的方法,或者是否有一些更“Pythonic”的编码方法可以完全避免这个问题?


Tags: 数据对象内存代码numpy脚本光栅代表
2条回答

你不需要关心自己的内存管理,尤其是垃圾回收器,它有一个非常具体的任务,你很可能根本不使用。Python将始终收集它所能收集的内存并重用它。

出现问题的原因只有两个:要么你试图加载的数据太多,无法放入内存,要么你的计算将数据存储在某个地方(列表、dict、迭代之间的持久性内容),并且存储会不断增长。Memory profilers can help正在查找。

del语句是“强制”垃圾收集器清除临时循环对象的一种快速方法:

for obj in list_of_obj:   
    data = obj.getData()  
    do_stuff(data)   
    del data 

这迫使解释器删除并释放临时对象。注意:这不能确保程序在计算的其他部分不会泄漏或消耗内存,这只是一个快速检查

相关问题 更多 >