使用类函数和类属性进行多处理

时间:2016-11-25 11:01:42

标签: oop pandas multiprocessing python-3.5

我有一个pandas Dataframe,它有数百万行,我必须做行式操作。由于我有一个多核CPU,我想使用多处理加速该过程。我想这样做的方法是将数据帧分成大小相同的数据帧,并在一个单独的进程中处理每个数据帧。到现在为止还挺好... 问题是,我的代码是用OOP样式编写的,我使用Multiprocess Pool得到了Pickle错误。我所做的是,我将对类函数self.X的引用传递给池。我进一步使用X中的类属性(仅读访问)。我真的不想切换回函数编程风格......因此,是否可以在OOP环境中进行多处理?

1 个答案:

答案 0 :(得分:0)

只要您的类中的所有元素(传递给子流程)都是可选的,就应该可以实现。这是你必须确保的唯一事情。如果您的班级中有任何元素没有,那么您无法将其传递给池。即使您只通过了self.x,其他所有内容也都可以选择self.y

我像我那样做我的pandas Dataframe处理:

import pandas as pd
import multiprocessing as mp
import numpy as np
import time


def worker(in_queue, out_queue):
    for row in iter(in_queue.get, 'STOP'):
        value = (row[1] * row[2] / row[3]) + row[4]
        time.sleep(0.1)
        out_queue.put((row[0], value))

if __name__ == "__main__":
    # fill a DataFrame
    df = pd.DataFrame(np.random.randn(1e5, 4), columns=list('ABCD'))

    in_queue = mp.Queue()
    out_queue = mp.Queue()

    # setup workers
    numProc = 2
    process = [mp.Process(target=worker,
                          args=(in_queue, out_queue)) for x in range(numProc)]

    # run processes
    for p in process:
        p.start()

    # iterator over rows
    it = df.itertuples()

    # fill queue and get data
    # code fills the queue until a new element is available in the output
    # fill blocks if no slot is available in the in_queue
    for i in range(len(df)):
        while out_queue.empty():
            # fill the queue
            try:
                row = next(it)
                in_queue.put((row[0], row[1], row[2], row[3], row[4]), block=True)  # row = (index, A, B, C, D) tuple
            except StopIteration:
                break
        row_data = out_queue.get()
        df.loc[row_data[0], "Result"] = row_data[1]

    # signals for processes stop
    for p in process:
        in_queue.put('STOP')

    # wait for processes to finish
    for p in process:
        p.join()

这样我就不必传递大块的DataFrame,而且我不必考虑我班级中的可选元素。