大熊猫Dataframe并行处理

时间:2015-11-09 15:50:55

标签: python pandas joblib

我正在访问一个非常大的Pandas数据帧作为全局变量。通过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在任何子进程中都没有被改变? (或者是吗?)

2 个答案:

答案 0 :(得分:10)

整个DataFrame需要为joblib创建的每个进程进行pickle和unpickled。在实践中,这非常慢并且还需要很多次的记忆。

一种解决方案是使用表格格式将数据存储在HDF(df.to_hdf)中。然后,您可以使用select选择数据子集以进行进一步处理。在实践中,这对于交互式使用来说太慢了。它也非常复杂,您的工作人员需要存储他们的工作,以便在最后一步中进行整合。

另一种方法是使用numba.vectorize探索target='parallel'。这将需要使用NumPy数组而不是Pandas对象,因此它也有一些复杂性成本。

从长远来看,dask希望为熊猫带来并行执行,但这不是一件容易让人期待的事情。

答案 1 :(得分:1)

正如您所指出的,Python多处理通常使用单独的进程完成,这意味着进程不共享内存。如果你可以将np.memmap的内容与joblib文档稍微提下一点,那么就有一个潜在的解决方法,尽管转储到磁盘显然会增加一些自己的开销:https://pythonhosted.org/joblib/parallel.html#working-with-numerical-data-in-shared-memory-memmaping