【发布时间】:2014-02-10 21:01:41
【问题描述】:
继this question 之后,我实现了两个功能做同样的事情,一个使用重新索引,另一个不使用。第 3 行的功能不同:
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 笔记本单元调用函数:
for centroid in centroids:
centroid = [update(centroid) for centroid in centroids]
数据框df 是一个大型数据框,大约有 400 万行,占用大约 300MB 内存。
使用重新索引的update1 函数要快得多。但是,发生了一些意想不到的事情 - 在运行重新索引内存的几次迭代后,内存迅速从〜300MB上升到1.5GB,然后我得到内存违规。
update 函数不会出现这种行为。两件事我没有得到:
重新索引会生成副本,这很明显。但是每次 update1 功能完成时,该副本不是应该死吗?
newdf变量应该随着创建它的函数而死。对吗?即使垃圾收集器没有立即杀死
newdf,一个内存用完了,它也应该杀死它并且不会引发 outOfMemory 异常,对吧?我尝试在 update1 函数末尾添加
del newdf手动杀死 df,但没有帮助。那么这是否表明该错误实际上是在重新索引过程本身中?
编辑:
我发现了问题,但我无法理解这种行为的原因。它是 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 变量如何与分数值保持联系,为什么?
【问题讨论】:
-
请把你的 python 和 pandas 版本升级;您正在运行 64-但是对吗?你至少有 4GB 吧?
-
运行 pandas '0.12.0' 32 位和 8GB 内存。但这似乎不是导致问题的重新索引。请参阅下面的评论..
-
32 位限制为 2GB 的实际空间和 4GB 的总内存(额外的内存没有任何作用);实际上,您将很难分配> 1GB(因为通常python需要一个连续的空间)。你会在 64 位上取得更大的成功
-
我发现了问题并编辑了问题(底部),您的想法将得到高度评价
-
关于您的更新:您每次都在创建一个新对象,因为您持有对每个对象的引用,您的内存将无限增长。
标签: python pandas ipython ipython-notebook