无法在队列中放置()+ get()更大的DataFrame

时间:2017-09-14 11:12:28

标签: python python-3.x pandas multiprocessing python-multiprocessing

下面的代码模拟了我面临的多处理问题。

有两个函数 - f1 f2 - 将带有 n 行的数据帧返回(pandas)到调用函数 run_fns (N)。这两个函数将并行运行。

该代码适用于较小的 n 值(例如n <= 700),但冻结较大的 n 值(比如n> = 7000)

我尝试使用队列([maxsize])调用队列,其中包含各种maxsize值,包括默认值,0,-1以及其他许多小而大的数字改变这种行为。

非常欢迎任何解决方案,变通方法或替代方法。我还有一个次要问题:我真的需要加入

if __name__ == "__main__":

某处?如果是这样的话?

代码: f1返回n行和3列,f2返回n行和5列。数据帧是使用随机生成的整数构建的。

import numpy as np
import pandas as pd
from multiprocessing import Process, Queue


def run_fns(n):
    """Run p1 and p2 in parallel, and get the returned dataframes."""
    q1 = Queue()
    q2 = Queue()
    p1 = Process(target=f1, args=(n, q1))
    p2 = Process(target=f2, args=(n, q2))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    df1 = q1.get()
    df2 = q2.get()
    return df1, df2


def f1(n, q):
    """Create a dataframe with n rows and 3 columns."""
    df = pd.DataFrame(np.random.randint(n * 3, size=(n, 3)))
    q.put(df)


def f2(n, q):
    """Create a dataframe with n rows and 5 columns."""
    df = pd.DataFrame(np.random.randint(n * 5, size=(n, 5)))
    q.put(df)

1 个答案:

答案 0 :(得分:3)

您正面临着多处理programming guidelines中记录的典型问题。

  

请记住,将项目放入队列的进程将在终止之前等待,直到所有缓冲的项目由“feeder”线程提供给底层管道。 (子进程可以调用队列的Queue.cancel_join_thread方法来避免此行为。)

     

这意味着无论何时使用队列,您都需要确保在加入进程之前最终删除已放入队列的所有项目。否则,您无法确定已将项目放入队列的进程将终止。

您需要确保在加入流程之前获取数据。

# start the processes
p1.start()
p2.start()
# drain the queues
df1 = q1.get()
df2 = q2.get()
# then join the queues
p1.join()
p2.join()

return df1, df2