14

我正在访问一个非常大的 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 在任何子进程中都没有改变?(或者是吗?)

4

2 回答 2

13

对于joblib创建的每个进程,需要对整个DataFrame进行pickle和unpickled。在实践中,这非常慢,并且还需要每个内存的许多倍。

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

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

从长远来看,dask有望为 Pandas 带来并行执行,但这并不是很快就能实现的。

于 2015-11-11T17:32:19.767 回答
3

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

于 2015-11-09T16:36:02.547 回答