【问题标题】:How do I loop through a large dataset in python without getting a MemoryError?如何在 python 中遍历大型数据集而不会出现 MemoryError?
【发布时间】:2010-11-04 15:18:39
【问题描述】:

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

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

脚本只是由循环语句包围的一长串数组代数方程。

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

不幸的是,我不能轻松地分块处理我的数据 - 我真的需要能够一次完成全部工作。这是因为,在每次迭代结束时,输出(水位)作为起点反馈到下一次迭代中。

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

我尝试阅读各种文档并发现了一种叫做“垃圾收集器”的东西,但我觉得我已经超出了我的深度,我的大脑正在融化!任何人都可以对我的代码循环时内存中的对象实际发生的情况提供一些基本的见解吗?有没有办法在每个循环结束时释放内存,还是有一些更“Pythonic”的编码方式可以完全避免这个问题?

【问题讨论】:

  • 如果不看一些源代码,我认为人们无法为您提供太多帮助。

标签: python memory


【解决方案1】:

您无需担心内存管理,尤其是垃圾收集器,因为垃圾收集器有非常具体的任务,您很可能甚至不会使用。 Python 将始终收集它可以收集的内存并重用它。

您的问题只有两个原因:您尝试加载的数据太多而无法放入内存,或者您的计算将数据存储在某个地方(列表、字典、迭代之间的持久性),并且存储空间不断增长。 Memory profilers can help 发现。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 2019-09-24
      • 2010-10-22
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      相关资源
      最近更新 更多