pd.DataFrame上的多处理没有加速?

时间:2017-09-28 11:17:22

标签: python pyspark python-multiprocessing

我正在尝试在pyspark上的大型pd.dataframe上应用函数。我的代码在下面发布,使用multiprocessing.Pool,但速度不如预期。它的成本与df.apply(f,axis=1)相同。

我没有注意到会有一些错误。我度过了我的一天,却一无所获。这就是为什么我终于来这里寻求帮助。

def f(series):
    # do something
    return series

if __name__=='__main__':
    #load(df)
    output=pd.DataFrame()
    pool = multiprocessing.Pool(8)
    for name in df.colunms:
        res=pool.apply_async(f,(df[name],),callback=logging.info("f with "+name))
        output[name]=res.get()
    pool.close()
    pool.join()

在@Andriy Ivaneyko回答之后,我也尝试了这个:

if __name__=='__main__':
    #load(df)
    output=pd.DataFrame()
    res={}
    pool = multiprocessing.Pool(8)
    for name in df.colunms:
        res[name]=pool.apply_async(f,(df[name],),callback=logging.info("f with "+name))
    for name,val in res.items():
        output[name]=val.get()
    pool.close()
    pool.join()

我将核心数量从4更改为8到16,但该功能消耗几乎相同的时间。

1 个答案:

答案 0 :(得分:0)

get()方法阻止功能完成,这是不获得性能优势的原因。创建ApplyResult对象的列表(由apply_async返回),并在完成get的迭代后执行df.colunms

# ... Code before
apply_results = []
for name in df.colunms:
        res=pool.apply_async(f,(df[name],),callback=logging.info("f with "+name))
        apply_results[name] = res

for name, res in apply_results.items():
    output[name]=res.get()
# ... Code after