非常に大きな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はどのサブプロセスでも変更されていないため、これは予期しないことですか? (またはそれは?)
Joblibによって作成されたプロセスごとに、DataFrame全体をピクル化およびピクルス解除する必要があります。実際には、これは非常に遅く、それぞれのメモリの何倍も必要です。
1つの解決策は、テーブル形式を使用してデータをHDF(df.to_hdf
)に保存することです。次に、select
を使用して、さらに処理するデータのサブセットを選択できます。実際には、これはインタラクティブに使用するには遅すぎます。また、非常に複雑であり、最終ステップで統合できるように、作業者は作業を保存する必要があります。
別の方法は、numba.vectorize
をtarget='parallel'
で探索することです。これには、Pandasオブジェクトではなく、NumPy配列を使用する必要があるため、複雑さのコストもかかります。
長期的には、 dask がパンダに並列実行をもたらすことが期待されていますが、これはすぐには期待できません。
前述のように、Pythonマルチプロセッシングは通常、個別のプロセスを使用して実行されます。つまり、プロセスはメモリを共有しません。 joblibドキュメントの少し下で述べたように、np.memmap
で動作させることができれば、潜在的な回避策がありますが、ディスクにダンプすると、明らかにそれ自体のオーバーヘッドが追加されます: https:// pythonhosted。 org/joblib/parallel.html#working-with-numerical-data-in-shared-memory-memmaping