Как несколько дочерних процессов могут записывать в один и тот же фрейм данных общей памяти в python? - PullRequest
1 голос
/ 20 апреля 2020

Мой python код использует многопроцессорность. В родительской программе есть фрейм данных, который создается в общей памяти, скажем, ns.df, где ns - это экземпляр менеджера пространства имен.

Несколько процессов должны добавить строки данных в этот файл ns.df, чтобы все изменения отражались после завершения процессов в родительской программе.

Процессы не обязаны взаимодействовать друг с другом, так как в них нет обмена или передачи данных между процессами. Данные, которые должны быть записаны каждым процессом, являются исключительными и независимыми только от этого процесса.

Woluld делает простое

ns.df = pd.concat([ns.df, tempdf], axis=0, sort=True)

внутри каждого из дочерних процессов. в достижении желаемого результата? Здесь tempdf будет фрейм данных с необходимыми данными, которые будут добавлены в ns.df.

Как я могу добиться этого в python? Любая помощь будет оценена.

1 Ответ

2 голосов
/ 20 апреля 2020

Я бы не стал добавлять строки в ns.df внутри каждого дочернего процесса в отдельности, а собирал их после завершения каждого дочернего процесса. Посмотрите на этот пример:

from concurrent.futures import ProcessPoolExecutor

import pandas as pd

def child_process(child_id):
    return pd.DataFrame({"column": [f"child_{child_id}"]})

df_main = pd.DataFrame({"column": ["parent"]})

with ProcessPoolExecutor(max_workers=4) as pool:
    child_dfs = list(pool.map(child_process, range(5)))

df_all = pd.concat([df_main, *child_dfs])
print(df_all)

Вывод

    column
0   parent
0  child_0
0  child_1
0  child_2
0  child_3
0  child_4

Если вы изменили ns.df внутри каждого дочернего процесса, это будет фактически объект общей памяти.

Предупреждение: если возвращаемые кадры данных дочерних процессов очень велики, то использование многопроцессорной обработки может привести к значительным накладным расходам, поскольку кадры данных должны быть обработаны перед их повторной загрузкой в ​​главном процессе. В зависимости от того, что делает настоящий дочерний процесс (может быть, много операций ввода-вывода или он использует C функции, которые выпускают GIL), может быть лучше вместо этого использовать многопоточность.

...