【问题标题】:Python memory allocation with pandas and pickle使用 pandas 和 pickle 分配 Python 内存
【发布时间】:2017-02-20 09:35:03
【问题描述】:

我正在运行一个 python 脚本,可以大致总结(半伪编码)如下:

import pandas as pd
for json_file in json_files:
    with open(json_file,'r') as fin:
        data = fin.readlines()
    data_str = '[' + ','.join(x.strip() for x in data) + ']'
    df = pd.read_json(data_str)
    df.to_pickle('%s.pickle' % json_file)
    del df, data, data_str

该过程以迭代方式创建数据框,并将它们各自保存到一个唯一的文件中。但是,我的内存似乎在这个过程中被耗尽了,好像del df, data, data_str 没有释放内存(本来我没有在代码中包含del 语句,但我希望添加它可以解决问题 - - 它没)。在每次迭代期间,大约相同数量的数据被读入数据帧,大约是我可用内存的 3%;随着进程的迭代,每次迭代都报告了%MEM(来自我的终端中的ps u | grep [p]ython)的 3% 颠簸,最终我的内存被淹没并且进程被杀死。我的问题是我应该如何更改我的代码/方法,以便在每次迭代时释放上一次迭代的内存?

请注意,我通过 Anaconda 运行带有 Python 3.5.2 的 Ubuntu 16.04。

提前感谢您的指导。

【问题讨论】:

  • 你是对的,你不需要delfor 循环中的变量,因为每次在循环中重新绑定变量时,旧对象的引用计数都会减少。他们在for 完成后闲逛,但如果这是在一个函数中,那么该引用也会消失。我唯一的猜测是clean_json_to_str 可能会做一些不好的事情,比如保留对该对象的背景引用。
  • 非常感谢您的回答@tdelaney。我已经更新了我的问题,使clean_json_to_str 步骤更加明确,并对我在del 调用中投入的所有内容诚实(尽管正如你所提到的,这不应该是问题)。
  • 我创建了你的代码版本,我可以测试here,它没有显示出奇怪的内存消耗。您可能会遇到一些颠簸,因为底层堆在前几次迭代中扩展并且有空的可用空间。但这平衡了,对我来说,内存没有增加。
  • 为什么要腌制基于 JSON 的数据帧?一般来说,酸洗不是内存效率的,并且对于基于 JSON 的对象来说有点多余。酸洗详情见hbfs.wordpress.com/2013/01/08/python-memory-management-part-ii。我只需将清理后的 JSON 保存在不同的文本文件中,并在需要时使用 json 模块读取它。
  • @tdelaney 感谢您的代码并对此进行调查。这对我来说真的很奇怪,而且我的行为方式与你的结果不一致。

标签: python memory-management memory-leaks


【解决方案1】:

在 python 中,自动垃圾回收会释放变量(pandas DataFrame 也只是 python 的另一个对象)。可以调整不同的垃圾收集策略(需要大量学习)。

您可以使用手动触发垃圾收集

import gc
gc.collect()

但不鼓励频繁调用垃圾回收,因为这是一项代价高昂的操作并且可能会影响性能。

Reference

【讨论】:

  • 只有在简单的对象引用计数不足以确定是否需要删除(例如循环引用)时才需要垃圾收集。在 OP 的情况下不需要它并且不会解决问题。
猜你喜欢
  • 2016-03-16
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多