熊猫& Scikit:切片DataFrame时的内存使用情况

时间:2012-09-01 11:54:47

标签: python pandas scikit-learn

我有一个很大的DataFrame,从csv文件加载(大约300MB)。

由此,我提取了几十个要在RandomForestClassifier中使用的功能:一些功能只是从数据中的列派生而来,例如:

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

其他人使用原始数据框中的索引从numpy数组创建为新的DataFrame

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]

然后为我的随机森林构建树突然需要许多千兆字节的内存 - 即使功能DataFrame的大小现在是原始的O(10%)。

我可以相信这可能是因为对数据的切片视图不允许进一步切片有效地完成(虽然我不知道我如何将其传播到features数组中),所以我试过了:

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

但这没有帮助。

  • 为什么要取一部分数据会大量增加内存使用量?
  • 是否还有其他方法来压缩/重新排列DataFrame,这可能会让事情再次变得更有效率?

1 个答案:

答案 0 :(得分:4)

RandomForestClassifier正在内存中多次复制数据集,尤其是当n_jobs很大时。我们知道这些问题,并且优先解决这些问题:

  • 我目前正在研究标准库的multiprocessing.Pool类的子类,当numpy.memmap实例传递给子进程工作者时,它不会执行内存复制。这样就可以共享源数据集的内存+工作者之间的一些预先计算的数据结构。修复后,我将关闭this issue on the github tracker

  • 有一个ongoing refactoring会将RandomForestClassifier的内存使用量进一步减少两倍。然而,重构的当前状态是主节点的两倍,因此仍需要进一步的工作。

然而,这些修复程序都没有达到计划于下周发布的0.12版本。最有可能的是他们将完成0.13(计划在3到4个月内发布),但很快就会在主分支中提供。“/ p>