2012-09-01 17 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