多处理,传递字典并返回数据框

multiprocessing, pass a dictionary & have a dataframe returned

我是 python 中的多处理新手。我有一个任务需要大约 10 分钟才能完成 运行 并且它需要 运行 多次(不同的参数)并且似乎多处理是减少总 运行 时间的好选择。

我的代码是一个简单的测试,并不像我预期的那样 运行ning,显然我做错了什么。没有任何内容打印到控制台,列表 processes 被 returned 但不是数据帧而是 Process 对象。

我需要向我的函数传递一个字典,它在 return 中将 return 一个数据框,我该怎么做?

import time
import pandas as pd
import multiprocessing as mp


def multiproc():

processes = []

settings = {1: {'sleep_time': 5,
                'id': 1},
    2: {'sleep_time': 1,
                'id': 2},
    3: {'sleep_time': 2,
                'id': 3},
    4: {'sleep_time': 3,
                'id': 4}}

for key in settings:
    p = mp.Process(target=calc_something,  args=(settings[key],))
    processes.append(p)
    p.start()
    
for p in processes:
    p.join()
    
return processes

def calc_something(settings: dict) -> pd.DataFrame:

   time_to_sleep = settings['sleep_time']
   time.sleep(time_to_sleep)
   print(str(settings['id']))

df = some_function_creates_data_frame()

return df

尽管你的缩进有误,我还是会冒险猜测你的意图。

当您提交要处理的多个任务并且您想要限制用于处理这些任务的处理器数量或者您需要从任务返回 return 值时,表明使用进程池(还有其他方法 return 从进程返回值,例如使用队列,但是使用进程池可以使这变得容易)。

import time
import pandas as pd
import multiprocessing as mp


def calc_something(settings: dict) -> pd.DataFrame:

    time_to_sleep = settings['sleep_time']
    time.sleep(time_to_sleep)
    print(str(settings['id']))

    df = pd.DataFrame({'sleep_time': [time_to_sleep], 'id': [settings['id']]})
    return df


def multiproc():

    settings = {1: {'sleep_time': 5,
                    'id': 1},
        2: {'sleep_time': 1,
                    'id': 2},
        3: {'sleep_time': 2,
                    'id': 3},
        4: {'sleep_time': 3,
                    'id': 4}}

    with mp.Pool() as pool:
        data_frames = pool.map(calc_something, settings.values())
    return data_frames

if __name__ == '__main__': # required for Windows
    data_frames = multiproc()
    for data_frame in data_frames:
        print(data_frame)

打印:

2
3
4
1
   sleep_time  id
0           5   1
   sleep_time  id
0           1   2
   sleep_time  id
0           2   3
   sleep_time  id
0           3   4

重要提示

在 Windows 或任何不使用 fork 的平台下创建进程时,创建这些进程的代码必须在 if __name__ == '__main__': 块中调用,否则您将进入产生新进程的递归循环。这可能是您问题的一部分,但很难说,因为除了缩进问题之外,您还没有 post minimum, reproducible example.