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中都在命令行中测试了代码,但是两种情况下的行为都是相同的。