【发布时间】:2021-06-08 14:25:55
【问题描述】:
我在这个问题上工作了几个小时,但找不到解决方案。我正在运行一个循环并在一个相对较大的 DataFrame 上进行一些计算。但是随着每个循环,虚拟内存使用量都会增加,直到内存不足。我尝试手动垃圾收集,设置 gc 和库(如 pymler 和 objgraph)的默认阈值以查找此行为的原因,但没有成功。
我创建了一个最小的代码示例,它在 8gb 的 RAM 和约 7gb 的分页文件上在几秒钟内用完内存:
import pandas as pd
import numpy as np
import time
import psutil
import os
def some_operations(data):
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
return data1
if __name__=="__main__":
data = pd.DataFrame(np.random.random((7000000, 13)))
data[0] = data[0] > 0.5
for j in range(500):
tack = time.time()
very_important_variable = some_operations(data)
p = psutil.Process(os.getpid())
memory_use = p.memory_info().vms / 1024 ** 2
tick = time.time()
print(f"Iteration: {j}, took {tick - tack:.2f} seconds and {memory_use/1000:.2f} GB of memory")
任何想法为什么会发生这种情况?内存信息告诉我,每个循环都会向虚拟内存添加约 540MB。
非常感谢!
更新:
似乎 Python 没有正确地取消分配 some_operations 的 groupby 操作。即使我在函数内部del data 和gc.collect(),它也不会改变任何东西。通过分配简单的变量而不是 groupby 函数发现了这一点。
之后我如何才能真正强制 Python 释放内存? del 和 gc.collect() 似乎不起作用。
还在积累内存:
def some_operations(data):
data1 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data2 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data3 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data4 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
data5 = data.groupby(0)[2].shift(-5).rolling(window=5, min_periods=1).max()
result = data1 + data2 + data3 + data4 + data5
del data1, data2, data3, data4, data5
gc.collect()
return result
【问题讨论】:
-
我认为
data.groupby的调用次数可能是原因。分组是一个“昂贵”的操作,你在一个非常大的数据集上使用它几次。为了获得更好的性能,pyspark包通常比 pandas 快得多。 -
谢谢,那我正在尝试测试火花!
标签: python python-3.x pandas memory-leaks out-of-memory