Совместное использование объектов между работниками с помощью пиарроу
Я хотел бы предоставить доступ только для чтения к общему DataFrame нескольким рабочим процессам, созданным multiprocessing.Pool.map()
,
Я хотел бы избежать копирования и маринования.
Я понял, что пиарроу можно использовать для этого. Однако я нахожу их документацию довольно громоздкой. Кто-нибудь может привести пример того, как это можно сделать?
1 ответ
Пример по адресу https://github.com/apache/arrow/blob/master/python/examples/plasma/sorting/sort_df.py представляет собой рабочий пример, который разделяет фрейм данных Pandas между несколькими работниками, использующими многопроцессорную обработку Python (обратите внимание, что для этого требуется вам построить небольшую библиотеку Cython для того, чтобы запустить ее).
Кадр данных передается через хранилище объектов Arrow Plasma.
Если вы не привязаны к многопроцессорной обработке Python, вы можете использовать Ray, чтобы делать то, что вы хотите, с более простым синтаксисом.
Чтобы предоставить нескольким работникам доступ только для чтения к фрейму данных Pandas, вы можете сделать следующее.
import numpy as np
import pandas
import ray
ray.init()
df = pandas.DataFrame(np.random.normal(size=(1000, 10)))
@ray.remote
def f(df):
# This task will run on a worker and have read only access to the
# dataframe. For example, "df.iloc[0][0] = 1" will raise an exception.
try:
df.iloc[0][0] = 1
except ValueError:
pass
return df.iloc[0][0]
# Serialize the dataframe with pyarrow and store it in shared memory.
df_id = ray.put(df)
# Run four tasks that have access to the dataframe.
result_ids = [f.remote(df_id) for _ in range(4)]
# Get the results.
results = ray.get(result_ids)
Обратите внимание, что линия df_id = ray.put(df)
можно опустить (и вы можете напрямую позвонить f.remote(df)
). В таком случае, df
будет по-прежнему храниться в общей памяти и совместно с рабочими, но будет храниться 4 раза (один раз для каждого вызова f.remote(df)
), что менее эффективно.