qkh*_*hly 6 python memory pandas
我的代码包含这个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)]
Run Code Online (Sandbox Code Playgroud)
A
是一只DataFrame
看起来像这样的熊猫:
score coordinate
0 0.158 1
1 0.167 2
2 0.175 3
3 0.183 4
4 0.190 5
Run Code Online (Sandbox Code Playgroud)
我试图找到最大分数(一个峰值)A
,然后在先前找到的峰值周围排除一些坐标(在这种情况下为几百个),然后找到下一个峰值,依此类推.
A
这是一只非常大的熊猫DataFrame
.在运行此while
循环之前,ipython会话使用了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
Run Code Online (Sandbox Code Playgroud)
你的DataFrame
规模太大了,无法处理。当您执行此行时,内存负载会加倍:
A = A.loc[(A.coordinate <= one_center - exclusion) | (A.coordinate >= one_center + exclusion)]
Run Code Online (Sandbox Code Playgroud)
这是因为您要为 分配一个新值,因此在过滤旧值时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)]
Run Code Online (Sandbox Code Playgroud)
top
在迭代之间按 Enter 键,并使用或类似工具密切关注内存使用情况。
在第一次迭代开始时,您将看到内存使用百分比x
。在第二次迭代中,loc
第一次调用后,内存使用量翻倍至2x
。4x
随后,您将看到它在每次调用期间上升到,然后在垃圾回收之后loc
下降到。2x
归档时间: |
|
查看次数: |
1727 次 |
最近记录: |