如何在Python中遍历大型数据集而不出现MemoryError?
我有一大堆栅格数据集,代表了好几年的每月降雨量。我写了一个Python脚本,循环处理每个栅格,具体步骤如下:
- 把栅格转换成一个numpy的掩码数组,
- 进行很多数组运算来计算新的水位,
- 把结果写入一个输出栅格。
- 重复以上步骤。
这个脚本其实就是一长串的数组运算公式,放在一个循环语句里。
如果我只处理一小部分数据(比如20年的数据),一切都运行得很好,但如果我试图处理所有数据,就会出现一个MemoryError
的错误。这个错误没有提供更多的信息(除了指出Python在哪一行代码上停止了)。
不幸的是,我不能轻易地把数据分成小块来处理——我真的需要一次性处理所有数据。这是因为在每次循环结束时,输出的水位会作为下一次循环的起点。
我目前对编程的理解非常基础,但我以为我的所有对象在每次循环时都会被覆盖。我(可能有点傻?)以为如果代码能成功循环一次,那它就应该能无限循环下去,而不会消耗越来越多的内存。
我尝试阅读了一些文档,发现了一个叫“垃圾回收器”的东西,但我感觉自己有点迷茫,脑袋都快炸了!有没有人能简单解释一下,当我的代码循环时,内存中的对象到底发生了什么?有没有办法在每次循环结束时释放内存,或者有没有什么更“Pythonic”的编码方式可以完全避免这个问题?
2 个回答
4
一种快速“强制”垃圾回收器清理临时循环对象的方法是使用 del 语句:
for obj in list_of_obj:
data = obj.getData()
do_stuff(data)
del data
这会强制解释器删除并释放这些临时对象。注意:这并不能保证程序在其他地方不会出现内存泄漏或消耗内存,它只是一个快速的检查。
5
你不需要担心内存管理,尤其是垃圾回收器,它有一个非常具体的任务,而你很可能根本用不到。Python会自动回收它能收集到的内存,并加以重用。
你遇到的问题主要有两个原因:要么你尝试加载的数据太多,超出了内存的承载能力,要么你的计算过程中存储了一些数据(比如列表、字典,或者在循环之间保持不变的数据),这些存储的内容不断增加。内存分析工具可以帮助你找到问题所在。