在继续从this question开始,我实现了两个函数,一个在使用重新索引,另一个没有。第三行的功能不同:
def update(centroid):
best_mean_dist = 200
clust_members = members_by_centeriod[centroid]
for member in clust_members:
member_mean_dist = 100 - df.ix[member].ix[clust_members].score.mean()
if member_mean_dist<best_mean_dist:
best_mean_dist = member_mean_dist
centroid = member
return centroid,best_mean_dist
def update1(centroid):
best_mean_dist = 200
members_in_clust = members_by_centeriod[centroid]
new_df = df.reindex(members_in_clust, level=0).reindex(members_in_clust, level=1)
for member in members_in_clust:
member_mean_dist = 100 - new_df.ix[member].ix[members_in_clust].score.mean()
if member_mean_dist<best_mean_dist:
best_mean_dist = member_mean_dist
centroid = member
return centroid,best_mean_dist
正在从IPython笔记本单元调用函数:
^{pr2}$dataframedf
是一个大数据帧,大约有400万行,占用~300MB内存。在
使用重新索引的update1
函数要快得多。但是,一些意想不到的事情发生了-在运行一个重新索引的迭代之后,内存很快就从~300MB增加到1.5GB,然后我得到内存冲突。在
update
函数不受这种行为的影响。有两件事我得不到:
很明显,重新索引会产生副本。但是,每次update1函数完成时,副本不都会消亡吗?newdf
变量应该随着创建它的函数而消亡。。正确的?
即使垃圾回收器没有立即杀死newdf
,一个内存用完了,它也应该杀死它而不是引发outOfMemory异常,对吗?
我试图在update1函数的末尾添加del newdf
来手动杀死df,但没有帮助。那么,这是否意味着bug实际上是在重新索引过程中呢?
编辑:
我发现了问题,但我不明白为什么会有这种行为。它是python垃圾收集器,拒绝清理重新编制索引的数据帧。 这是有效的:
for i in range(2000):
new_df = df.reindex(clust_members, level=0).reindex(clust_members, level=1)
这也是有效的:
def reindex():
new_df = df.reindex(clust_members, level=0).reindex(clust_members, level=1)
score = 100 - new_df.ix[member].ix[clust_members].score.mean()
return score
for i in range(2000):
reindex()
这会导致在内存中保留重新索引对象:
z = []
for i in range(2000):
z.append(reindex())
我认为我的用法是天真的正确。newdf
变量如何与得分值保持连接,为什么?在
这是我的调试代码,当你做索引时,Index object会创建},我想内存是由这两个缓存对象使用的。如果我添加
_tuples
和{****
标记的行,那么内存的增加非常小,在我的电脑上大约是6米:相关问题 更多 >
编程相关推荐