我目前正在将Pandas用于csv源文件约为600mb的项目。在分析过程中,我正在读取csv中的数据框,在某些列上进行分组,然后对分组的数据框应用简单的功能。我注意到在此过程中我要进入交换内存,因此进行了一个基本测试:
我首先在外壳中创建了一个相当大的数据框:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(3000000, 3),index=range(3000000),columns=['a', 'b', 'c'])
我定义了一个无意义的函数,称为do_nothing():
def do_nothing(group):
return group
并运行以下命令:
df = df.groupby('a').apply(do_nothing)
我的系统具有16gb的RAM,并且正在运行Debian(薄荷糖)。创建数据帧后,我使用的是〜600mb RAM。一旦apply方法开始执行,该值便开始飙升。在完成命令并稳定回落到5.4gb(外壳仍处于活动状态)之前,它稳定地上升到大约7gb(!)。问题是,我的工作需要做的事情比'do_nothing'方法还多,因此在执行实际程序时,我为16gb的RAM设置了上限并开始交换,从而使程序无法使用。这是故意的吗?我看不出为什么熊猫必须需要7gb的RAM才能有效地“不做任何事情”,即使它必须存储分组的对象也是如此。
关于导致此问题/如何解决的任何想法?
干杯,
.P
使用0.14.1,我不认为它们是内存泄漏(帧大小的1/3)。
In [79]: df = DataFrame(np.random.randn(100000,3))
In [77]: %memit -r 3 df.groupby(df.index).apply(lambda x: x)
maximum of 3: 1365.652344 MB per loop
In [78]: %memit -r 10 df.groupby(df.index).apply(lambda x: x)
maximum of 10: 1365.683594 MB per loop
关于如何解决这样的问题的两个一般性评论:
1)尽可能使用cython级别的功能,速度会更快,并且会占用更少的内存。IOW,使用功能解耦groupby表达式和void几乎总是值得的(如果可能的话,有些事情太复杂了,但这就是要分解的意思)。例如
代替:
df.groupby(...).apply(lambda x: x.sum() / x.mean())
最好做的是:
g = df.groupby(...)
g.sum() / g.mean()
2)您可以通过手动进行聚合来轻松地“控制”组(此外,如果需要,这将允许定期输出和垃圾回收)。
results = []
for i, (g, grp) in enumerate(df.groupby(....)):
if i % 500 == 0:
print "checkpoint: %s" % i
gc.collect()
results.append(func(g,grp))
# final result
pd.concate(results)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句