python.multiprocessing и изменение shared-memory object
Можно ли применить в multiprocessing функцию, которая имеет внутри цикл, в каждой итерации записывающий новую строку в результат?
Буду благодарен если напишите какие инструменты для этого нужны: manager(),Namespace(),lock() и т.д.
Еще больше буду благодарен за ссылку на похожие проблемы, самое близкое, что я нашел - https://www.appsloveworld.com/pandas/100/196/share-dataframe-in-python-multiprocessing
import multiprocessing
import heapq
import pandas as pd
def my_func(df):
df_res = pd.DataFrame(columns=['result1', 'result2'])
def insert_row(df, my_row):
df.loc[len(df)] = my_row
# modify df here
df2 = pd.read_csv # ...
df3 = pd.merge(df, df2, on=['field'])
# getting values here
for ix in df3.index:
dct = df2[df2['field'] == df3.loc[ix]['field']].values.tolist()
result1, result2 = heapq.heappop(dct)
# here i want to insert row into parent dataframe (df_res2) in the main process
# but now i use concat method below
insert_row(df_res, (result1, result2))
return df_res
if __name__ == "__main__":
df = pd.DataFrame({'a': [2, 2, 1, 1, 3, 3], 'b': [4, 5, 6, 4, 5, 6], 'c': [4, 5, 6, 4, 5, 6]})
df_res2 = pd.DataFrame(columns=['result1', 'result2'])
with multiprocessing.Pool(processes=(multiprocessing.cpu_count() - 1)) as pool:
groups = (g for _, g in df.groupby("a"))
print(df)
print(groups)
out = []
for res in pool.imap_unordered(my_func, groups):
out.append(res)
final_df = pd.concat(out)
EDITED: Так как мой пример упрощён - напишу саму задачу: Есть df - Операции, отсортированные по приоритетности. И df2 - ресурсы выполнения задачи (например люди) и их фонды рабочего времени. Для каждой операции в определённый месяц подбирается исполнитель с наибольшим фондом рабочего времени. После этого фонд исполнителя в df2 уменьшается на трудоемкость операции. В текущей версии все решается в цикле с помощью heapq.heappop() - который подбирает свободного исполнителя. Почему цикл? - присутствуют дополнительные вычисления в каждой итерации - после подбора нужно уменьшить фонд подобранного исполнителя до расчета следующей итерации, а также создаются доп переменные: успеют или нет, возможно нужно подобрать второго исполнителя и т.д. Альтернативы циклу для такого я не нашел - а мультипроцессинг в этом плане очень помогает - ведь можно независимо рассчитать на каждый месяц и сделать это быстро, так от меня и хотят))