如何在Python中循环遍历大型数据集而不出现MemoryError?

11
我有一系列大量的栅格数据集,代表了几十年的月降雨量。我用Python编写了一个脚本,循环遍历每个栅格数据集,执行以下操作:
  1. 将栅格转换为numpy遮罩数组,
  2. 进行大量的数组运算来计算新的水位,
  3. 将结果写入输出栅格.
  4. 重复以上步骤。
如果我只在我的一小部分数据上运行脚本(例如20年份),那么一切都很顺利,但是如果我试图处理整个数据集,我会得到一个MemoryError。除了指出Python放弃的代码行之外,该错误没有提供任何更多的信息。
不幸的是,我不能轻松地将我的数据分块处理 - 我真的需要能够一次性处理所有数据。这是因为,在每次迭代结束时,输出(水平面)将作为下一次迭代的起点反馈回去。
目前我的编程理解非常基础,但我认为所有对象都只是在每个循环中被覆盖。我(愚蠢地?)假设如果代码成功循环一次,那么它应该能够无限循环而不会使用更多的内存。
我尝试阅读各种文档,并发现了一些叫做"垃圾回收器"的东西,但我感觉自己正在深入地学习,我的大脑都快糊了!有人能够提供一些关于当我的代码循环时对象在内存中实际发生的事情的基本见解吗?是否有一种方法可以在每个循环结束时释放内存,或者是否有一种更“Pythonic”的编码方式可以避免这个问题?

1
我认为如果没有看到一些源代码,人们可能无法提供太多帮助。 - GWW
2个回答

5

您不需要关心内存管理,特别是那些具有非常特定任务的垃圾回收器,您很可能甚至没有使用过。Python将始终收集它可以收集的内存并重复使用。

造成问题的原因只有两个:要么您尝试加载的数据太多而无法适应内存,要么您的计算将数据存储在某个地方(列表、字典、迭代之间持久存在的东西),并且这种存储不断增长。内存分析工具可以帮助找到这一点。


4
一个快速的方法来“强制”垃圾回收器清理临时的循环对象是使用del语句:
for obj in list_of_obj:   
    data = obj.getData()  
    do_stuff(data)   
    del data 

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接