2015-11-09 213 views
5

我正在訪問一個非常大的熊貓數據幀作爲全局變量。該變量通過joblib並行訪問。大熊貓數據幀並行處理

例如,

df = db.query("select id, a_lot_of_data from table") 

def process(id): 
    temp_df = df.loc[id] 
    temp_df.apply(another_function) 

Parallel(n_jobs=8)(delayed(process)(id) for id in df['id'].to_list()) 

以這種方式訪問​​原始DF似乎跨進程複製數據。這是意料之外的,因爲原來的df在任何子流程中都沒有被修改過? (或是否?)

回答

7

整個數據幀需要進行封裝和拆封由joblib創建的每個進程。在實踐中,這是非常緩慢的,也需要多次記憶每個。

一種解決方案是使用表格格式將數據存儲在HDF(df.to_hdf)中。然後您可以使用select選擇數據的子集進行進一步處理。實際上,這對於交互式使用來說太慢了。這也非常複雜,您的工作人員需要存儲他們的工作,以便在最後一步將其整合。

另一種方法是探索numba.vectorizetarget='parallel'。這需要使用NumPy數組而不是Pandas對象,所以它也有一些複雜性成本。

從長遠來看,dask是希望給熊貓帶來並行執行,但這不是很快就能期待的。

+1

我假設從http://stackoverflow.com/questions/10721915/shared-memory-objects-in-python-multiprocessing子過程wouldnt收到一個完整的副本,除非原來的對象被改變。 joblib是否打破了寫入時複製語義? – autodidacticon

+1

只有少數類型可以使用共享內存傳遞。熊貓物體不在此列表中。當調用'Parallel'時,joblib根據數組大小使用關鍵字參數'max_nbytes'自動處理numpy數組的內存共享。參見[joblib的網站](https://github.com/joblib/joblib/blob/master/doc/parallel_numpy.rst)。 另請參閱[此答案](http://stackoverflow.com/a/22487898/2551705)。 你當然可以使用NumPy數組來代替熊貓,你可能會看到加速。 –