在长期运行的 Python 进程中迭代大型数据集 - 内存问题?
Posted
技术标签:
【中文标题】在长期运行的 Python 进程中迭代大型数据集 - 内存问题?【英文标题】:Iterating over a large data set in long running Python process - memory issues? 【发布时间】:2012-06-09 03:11:52 【问题描述】:我正在开发一个长时间运行的 Python 程序(其中一部分是 Flask API,另一个是实时数据获取器)。
我的两个长时间运行的进程都经常迭代(API 甚至可能每秒执行数百次)在大型数据集(对某些经济系列的逐秒观察,例如价值 1-5MB 的数据,甚至更多的)。它们还可以在序列等之间进行插值、比较和计算。
在迭代/作为参数传递/处理这些大型数据集时,我可以练习哪些技术,以保持我的进程处于活动状态?例如,我应该使用 gc 模块并手动收集吗?
更新
我最初是一名 C/C++ 开发人员,用 C++ 编写部件没有问题(甚至会喜欢)。我只是有 0 经验这样做。我该如何开始?
任何建议将不胜感激。 谢谢!
【问题讨论】:
用large-data和memory替换large和data标签 【参考方案1】:如果不真正查看您的数据/算法,这很难说,但以下方法似乎是通用的:
确保您没有内存泄漏,否则它迟早会杀死您的程序。使用objgraph - 很棒的工具!阅读文档 - 它包含您在 python 程序中可能遇到的内存泄漏类型的很好示例。
尽可能避免复制数据。例如 - 如果您需要处理部分字符串或进行字符串转换 - 不要创建临时子字符串 - 使用索引并尽可能长时间保持只读状态。它可以使您的代码更复杂且更少“pythonic”,但这是优化的成本。
谨慎使用gc——它会让你处理一段时间不负责任,同时没有任何价值。阅读doc。简而言之:只有在有真正理由这样做时才应该直接使用 gc,例如 Python 解释器在分配大的临时整数列表后无法释放内存。
认真考虑重写 C++ 的关键部分。现在就开始考虑这个令人不快的想法,以便在数据变大时做好准备。严重的是,它通常以这种方式结束。您也可以尝试Cython,它可以加速迭代本身。
【讨论】:
【参考方案2】:使用大型数据集不一定会导致内存复杂化。只要您在查看和操作数据时使用合理的方法,您通常可以节俭地使用内存。
在构建处理数据的模型时,您需要考虑两个概念。
执行给定计算需要访问数据的最小元素是什么?例如,您可能有一个 300GB 的文本文件,其中填充了数字。如果您要计算数字的平均值,请一次读取一个数字以计算运行平均值。在此示例中,最小的元素是文件中的单个数字,因为这是我们数据集中在任何时间点都需要考虑的唯一元素。
如何对应用程序建模,以便在计算过程中一次一个地迭代访问这些元素?在我们的示例中,我们不是一次读取整个文件,而是'将一次从文件中读取一个数字。使用这种方法,我们使用少量内存,但可以处理任意大的数据集。与其在内存中传递对数据集的引用,不如传递数据集的 view,它知道如何按需从其中加载特定元素(一旦使用就可以释放)。这在原理上类似于缓冲,是许多迭代器采用的方法(例如,xrange
、open
的文件对象等)。
一般来说,诀窍是了解如何将您的问题分解为大小恒定的小块,然后将这些块逐个拼接在一起以计算结果。您会发现这些数据处理租户与构建支持大规模并行的应用程序密切相关。
看向gc
是在开枪。您只提供了您正在处理的内容的高级描述,但从您所说的来看,您没有理由需要通过在内存管理中四处寻找来使事情复杂化。根据您正在进行的分析类型,考虑调查numpy
,它旨在减轻繁重统计分析的负担。
【讨论】:
我得到的数据是从 SQL 中提取的。它是非线性的,必须在函数之间传递等。因此,我真的不知道如何分解它...... @user1094786 在不确切知道您对其中一些数据做了什么的情况下,很难为您提供指导。你能用一个你可能会做的计算类型的简单例子来更新你的问题吗?以上是关于在长期运行的 Python 进程中迭代大型数据集 - 内存问题?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 R/Python 中迭代/循环一个大型(>2GB)JSON 数据集? [复制]
在 Java Spark 中迭代大型数据集的最快且有效的方法
Spacy,在 python 中的大型数据集上使用 nlp.pipe,多处理导致进程进入睡眠状态。如何正确使用所有 CPU 内核?