gpt4 book ai didi

python - while 循环中累积的内存使用量

转载 作者:太空狗 更新时间:2023-10-29 23:58:29 28 4
gpt4 key购买 nike

我的代码包含这个 while 循环:

while A.shape[0] > 0:
idx = A.score.values.argmax()
one_center = A.coordinate.iloc[idx]
# peak_centers and peak_scores are python lists
peak_centers.append(one_center)
peak_scores.append(A.score.iloc[idx])
# exclude the coordinates around the selected peak
A = A.loc[(A.coordinate <= one_center - exclusion) | (A.coordinate >= one_center + exclusion)]

A 是一个 pandas DataFrame,如下所示:

   score  coordinate
0 0.158 1
1 0.167 2
2 0.175 3
3 0.183 4
4 0.190 5

我试图在 A 中找到最大分数(峰值),然后排除先前找到的峰值周围的一些坐标(在本例中为几百个),然后找到下一个峰值,依此类推在。

A 这里是一个非常大的 pandas DataFrame。在运行此 while 循环之前,ipython session 使用了 20% 的机器内存。我认为运行此 while 循环只会导致内存消耗下降,因为我从 DataFrame 中排除了一些数据。但是,我观察到内存使用量不断增加,有时机器内存会耗尽。

我在这里遗漏了什么吗?我需要在某处显式释放内存吗?

这是一个可以使用随机数据复制行为的简短脚本:

import numpy as np
import pandas as pd

A = pd.DataFrame({'score':np.random.random(132346018), 'coordinate':np.arange(1, 132346019)})
peak_centers = []
peak_scores = []
exclusion = 147
while A.shape[0] > 0:
idx = A.score.values.argmax()
one_center = A.coordinate.iloc[idx]
# peak_centers and peak_scores are python lists
peak_centers.append(one_center)
peak_scores.append(A.score.iloc[idx])
# exclude the coordinates around the selected peak
A = A.loc[(A.coordinate <= one_center - exclusion) | (A.coordinate >= one_center + exclusion)]

# terminated the loop after memory consumption gets to 90% of machine memory
# but peak_centers and peak_scores are still short lists
print len(peak_centers)
# output is 16

最佳答案

你的 DataFrame实在是太大了,无法处理。执行此行时内存负载加倍:

A = A.loc[(A.coordinate <= one_center - exclusion) | (A.coordinate >= one_center + exclusion)]

那是因为您要为 A 分配一个新值, 所以内存分配给一个新的 DataFrame而旧的正在过滤。新的几乎与旧的一样大,因为您选择了几乎所有的数据点。这为 A 的两个副本占用了足够的内存。 ,这还没有考虑 loc 用于簿记的额外内存。实现确实如此。

显然 loc导致 pandas 为数据的额外副本分配足够的内存。我不确定这是为什么。我认为这是某种性能优化。这意味着您最终消耗的内存使用量是 DataFrame 的四倍。 .一次loc完成并释放未分配的内存——您可以通过调用 gc.collect() 强制释放—内存负载下降到 DataFrame 大小的两倍.下次调用 loc ,一切都翻了一番,你又回到了四倍的负荷。再次收集垃圾,你又回到原来的两倍。只要您愿意,这种情况就会一直持续下去。

要验证发生了什么,请运行您的代码的修改版本:

import numpy as np
import pandas as pd
import gc

A = pd.DataFrame({'score':np.random.random(32346018), 'coordinate':np.arange(1, 32346019)})
peak_centers = []
peak_scores = []
exclusion = 147
count = 0
while A.shape[0] > 0:
gc.collect() # Force garbage collection.
count += 1 # Increment the iteration count.
print('iteration %d, shape %s' % (count, A.shape))
raw_input() # Wait for the user to press Enter.
idx = A.score.values.argmax()
one_center = A.coordinate.iloc[idx]
# peak_centers and peak_scores are python lists
peak_centers.append(one_center)
peak_scores.append(A.score.iloc[idx])
print(len(peak_centers), len(peak_scores))
# exclude the coordinates around the selected peak
A = A.loc[(A.coordinate <= one_center - exclusion) | (A.coordinate >= one_center + exclusion)]

在迭代之间按 Enter 键并使用 top 关注内存使用情况或类似的工具。

在第一次迭代开始时,您会看到内存使用情况 x百分。在第二次迭代中,在 loc 之后第一次被调用,内存使用量加倍到2x .随后,您会看到它上升到 4x。在每次调用 loc 期间,然后转到 2x垃圾回收后。

关于python - while 循环中累积的内存使用量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32189565/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com