Python多处理 - 棘手的用例,包括传递参数

时间:2017-07-20 00:48:21

标签: python python-multiprocessing

我在并行分配我的功能时遇到了问题。

问题陈述:我有2个坐标对列表,dfCdfO。对于dfC中的每个障碍,我计算了dfO在半径范围内r落入的数量dfC我目前有一个工作功能,但我试图看看我是否可以并行处理。

问题是:dfO可以单独拆分和处理......但每个工作人员dfO需要100%。我的方法是,让我先让这个并行工作 - 然后我会担心如何向工人分发import pandas as pd import numpy as np import multiprocessing as mp from multiprocessing import Pool, process import traceback from scipy.spatial import cKDTree # create 2 dataframes with random "coordinates" dfC=pd.DataFrame(np.random.np.random.randint(0,100,size=(50,2)), columns=list('xy')) dfO=pd.DataFrame(np.random.np.random.randint(0,100,size=(500,2)), columns=list('jk')) 的完整副本。除非有人能帮我解决这两个问题吗?

首先,这里是设置所有内容的代码:

dfC

以下是dfO的示例,+----+----+ | x | y | +----+----+ | 35 | 5 | +----+----+ | 96 | 18 | +----+----+ | 23 | 25 | +----+----+ | 20 | 7 | +----+----+ | 74 | 54 | +----+----+ 看起来很相似

# this function works on dfC, and adds a row which counts the number
# of objects in dfO which are within radius r
def worker_job(args):
    try:
        dfC, dfO, newcol, r = args

        mxC=dfC.as_matrix()
        mxO = dfO.as_matrix()

        # magic tree stuff
        C_Tree = cKDTree(mxC)
        O_Tree = cKDTree(mxO)

        listoflists = C_Tree.query_ball_tree(O_Tree, r, p=2.0, eps=0.0)

        counts=[]
        for i in listoflists:
            counts.append(len(i))

        s = pd.Series(counts)

        dfC[newcol] = s.values

    except:
        raise
        traceback.print_exc()
    else:
        return dfC

接下来,这里的功能就像魅力一样。我没有单独传递所有参数,而是故意这样做 - 准备一个主函数来并行调用它们(我无法找到一种方法来进行多处理) )。

args=[dfC,dfO,"new_column_name",3]

如果我创建这样的参数: worker_job(args)

当我自己运行它时它完美地工作: +----+----+-----------------+ | x | y | new_column_name | +----+----+-----------------+ | 35 | 5 | 4 | +----+----+-----------------+ | 96 | 18 | 1 | +----+----+-----------------+ | 23 | 25 | 0 | +----+----+-----------------+ | 20 | 7 | 1 | +----+----+-----------------+ | 74 | 54 | 2 | +----+----+-----------------+

# this function should control the multiprocessing
def Run_Parallel(Function, Num_Proc, args):
    try:
        pool = Pool(Num_Proc)
        parts = pool.map(Function,args)
        pool.close()
        pool.join()

        results_df = pd.concat(parts)

    except:
        pool.close()
        pool.terminate()
        traceback.print_exc()
    else:
        return results_df

现在,我尝试构建将控制并行工作程序并并行运行此函数的函数。这是我最大的努力:

Run_Parallel(worker_job,2,args)

它不会起作用。 ValueError: not enough values to unpack (expected 4, got 2)引发了有关dfO的错误。当它通过包装器时,必须在参数列表中发生一些事情。

我正在寻找有关此错误的指导,以及任何知道如何解决更大问题的人的奖励积分 - 这是我需要我的池包含100%的dfC而只是一个子集mylist = [[[1,2],[3,4]],[[8,9],[7,7]]] [[max(y[0] for y in x), min(y[1] for y in x)] for x in mylist] 为了提高效率。

1 个答案:

答案 0 :(得分:1)

答案是将参数作为列表列表传递。这也解决了分割数据帧的另一个问题(我认为池默认处理这个问题,但事实并非如此)。

正确的功能应如下所示:

# this function should control the multiprocessing
def Run_Parallel(Function, Num_Proc, args):
    dfC, dfO, newcol, r = args

    # to make lists of lists
    argslist=[]
    dfOlist=[]
    dfClist=[]
    resultlist=[]

    # split dfC into parts
    Cparts=np.array_split(dfC, Num_Proc)

    # build the lists
    for i in range(Num_Proc):
        argslist.append([Cparts[i],dfO,newcol,r])


    try:
        pool = Pool(Num_Proc)
        parts = pool.map(Function,argslist)
        pool.close()
        pool.join()

        results_df = pd.concat(parts)

    except:
        pool.close()
        pool.terminate()
        traceback.print_exc()
    else:
        return results_df