Python多处理-同时处理大量行

时间:2018-11-27 19:06:55

标签: python optimization multicore

SO社区

我正在努力进行Python多核编程。尽管由于公司的信息安全政策,我无法透露太多有关代码目标的细节,但我会尽力做到具体。

我正在开发一个代码,该代码将评估几个人的每周分数,根据他们的总体分数分为5组。我有一个相当大的数据框,由成千上万的行组成,每个行都有玩家的ID,所考虑的周(在九周的时间内)及其在给定周中的得分。最重要的是,我有五个索引数组,因此我可以根据他们的得分来定位/定位用于选择五个组之一中的人的数据。

我编写了此代码的序列化版本,但是要花一小时的时间来运行一小部分数据(大约15万行)(我正在开发一个小样本,因此可以测试该代码并,就可以了,我可以使用完整的数据集启动它)。 pythonesque伪代码中序列化代码的结构:

def weekscore(week, ID, players):
    mask(week)
    players.loc[players['player'==ID]
    score = (calculate score)
    return score

然后,对于所有玩家和整个星期:

sc_week = [] 
for play_ID in playerlist:
        for week in np.arange(0,10): # To consider 9 weeks
            sc_week.append(weekscore(week, play_ID, players)

即,对于列表中的每个玩家,获取给定一周的分数并附加到9个元素的列表中,以供进一步处理。

我知道这不是解决此问题的最佳方法,但是由于我尝试实现多核算法,因此我没有费心去优化这一算法。毕竟,这似乎是学习一项重要技能的绝好机会,以后会有用。

无论如何,我尝试了在SO上找到的每种方法来实现此问题的多处理算法。这个想法是将不同的player_ID委派给不同的进程,因此我可以大大减少总处理时间。我可以使用32核计算机,因此,如果我可以使用20核进行运行,那么我希望代码的运行速度至少快10倍,最低。

但是无论我实现了什么,即使代码将进程分为多个进程,它仍然一次只处理一个player_ID。我通过Linux上的htop以及Windows和这两个系统上的任务管理器监视执行情况,将池大小设置为8,创建了8个子进程。然后,其中一个将达到CPU的100%峰值,将某些内容输出到屏幕,然后另一个将达到100%的CPU峰值,输出到屏幕,另一个进程将达到100%的CPU峰值并输出,依此类推。我原本希望所有过程都能达到100%,但我无法做到这一点。

我最接近的是这个:

if __name__ == '__main__':
    users, primeiro, dados, index_pred_80, intervalos, percents_ = prepara()

    print('Multiprocessing step')
    import multiprocessing as mp
    from multiprocessing import freeze_support
    from functools import partial
    freeze_support()

    pool = mp.Pool(10)
    constparams = partial(perc1, week = week, ID = ID, players = players)
    pool.map(constparams, users)
    pool.close()
    pool.join()

调用函数perc1(出于隐私原因而匿名)

def perc1(week, ID, players):
    list1 = []
    for week in np.arange(0,10):
        mask(week)
        players.loc[players['player'==ID]

        print('Week = ', week, 'Player ID = ', player_ID)
        score = (calculate score)

        list1.append(score)
    return (lista1)

因此,经过漫长的讨论,实现此目标的最佳方法是什么?为不同的流程委派ID的批次的最佳方法是什么,以便每个流程都可以遍历一部分数据?

编辑1:修正了小的错字。

编辑2:我知道多核Python交互式解释器的局限性,因此我在Windows和Linux中都在命令行中测试了代码,但是两种情况下的行为都是相同的。

0 个答案:

没有答案