2012-09-01 21 views
2

我有一个大的DataFrame,从csv文件(约300MB)加载。Pandas&Scikit:切片时的内存使用情况DataFrame

从此,我提取几十功能于一身RandomForestClassifier使用方法:一些功能被简单地列在数据导出,例如:

feature1 = data["SomeColumn"].apply(len) 
feature2 = data["AnotherColumn"] 

而另外一些是作为新创建从numpy的阵列DataFrame S,使用在原始数据帧的索引:然后

feature3 = pandas.DataFrame(count_array, index=data.index) 

所有这些功能结合成一个DataFrame

features = feature1.join(feature2) # etc... 

我培养了随机森林分类:

classifier = RandomForestClassifier(
    n_estimators=100, 
    max_features=None, 
    verbose=2, 
    compute_importances=True, 
    n_jobs=n_jobs, 
    random_state=0, 
) 
classifier.fit(features, data["TargetColumn"]) 

RandomForestClassifier工作正常使用这些功能,构建树需要O(数百兆的内存)。 然而:如果加载我的数据后,我把它的集:

data_slice = data[data['somecolumn'] > value] 

然后建立一个树我随机森林突然发生许多GB的内存 - 即使的大小功能DataFrame现在是O(10%)的原始。

我可以相信这可能是因为对数据的切片视图不允许进一步的切片有效地完成(虽然我不明白我如何能够传播到特征数组),所以我已经尝试:

data = pandas.DataFrame(data_slice, copy=True) 

但这没有帮助。

  • 为什么会取数据的子集大量增加内存使用?
  • 是否有其他方式来压缩/重新排列DataFrame,这可能会使事情再次变得更有效率?
+1

这个问题看起来像是为kaggle比赛(预测stackoverflow封闭的问题)? – ronalchn

+0

@ronalrect correct;) – James

回答

3

RandomForestClassifier正在内存中复制数据集数次,特别是当n_jobs较大时。我们意识到这些问题,这是一个优先解决这些问题:

  • 我目前工作的multiprocessing.Pool类标准库的一个子类,会做任何内存拷贝时numpy.memmap实例传递到子工人。这样可以共享源数据集的内存+工作人员之间的一些预先计算的数据结构。一旦修复,我将关闭this issue on the github tracker

  • 有一个ongoing refactoring这将进一步减少内存使用RandomForestClassifier两个。然而,重构的当前状态比主控器慢两倍,因此仍需要进一步的工作。

但是,这些修复程序都不会使它成为下周计划发布的0.12版本。他们很可能会在0.13(计划在3到4个月内发布)完成,但主分支机构会尽快提供课外活动。

+0

当我仅使用一段数据时,是否有什么特别的原因会导致内存使用量急剧增加(至少十倍)? 'data = data [data ['col']> x]'。否则,内存使用是可管理的。 – James

+0

你的意思是你有10倍增加,甚至没有调用'RandomForestClassifier'?你有没有比较'n_jobs = 1'?另请注意,RandomForestClassifier将复制输入,使其与'dtypes = np.float64'同名的fortran排列的numpy数组。所以这可能是隐藏但预期的数据使用的另一个原因。 安装psutil和http://pypi.python.org/pypi/memory_profiler找到您的案件的罪魁祸首。 – ogrisel

+0

在拟合分类器时没有发生巨大的增加,但前提是正在使用的数据被切片(按照所述的布尔值索引)。 (数据被用作(某些)功能以及目标值)。这绝对不仅仅是一个额外的副本,我会用探查器进行调查。 – James