Python 多处理池方法的性能问题
我在一个数据框中有一列,它由一个项目列表组成,我想根据Fisher精确测试计算该数据框的行(在本例中为列表)与所有其他行的相似性。为此,我想使用python multiprocessing中的Pool,但它似乎占用了与传统方法差不多的时间(即使用嵌套For循环)。有什么方法可以优化代码吗 费希尔试验Python 多处理池方法的性能问题,python,multiprocessing,python-multiprocessing,Python,Multiprocessing,Python Multiprocessing,我在一个数据框中有一列,它由一个项目列表组成,我想根据Fisher精确测试计算该数据框的行(在本例中为列表)与所有其他行的相似性。为此,我想使用python multiprocessing中的Pool,但它似乎占用了与传统方法差不多的时间(即使用嵌套For循环)。有什么方法可以优化代码吗 费希尔试验 def fisher_test(a, b, c, d): # do some stuff and return p value 使用嵌套for循环进行计算: %%time import m
def fisher_test(a, b, c, d):
# do some stuff and return p value
使用嵌套for循环进行计算:
%%time
import multiprocessing as mp
pool = mp.Pool(mp.cpu_count())
universeSize = 13000
# gq_result_df is a data frame
for i, row in gq_result_df.iterrows():
for j in range(i, gq_result_df.shape[0]):
if(i==j):
continue
pval = fisher_test(row["module_genes"], gq_result_df.loc[j,"module_genes"], universeSize)
# pval_matrix is a matrix in which we are storing the result
pval_matrix[i,j] = pval
使用池并行化内部循环:
%%time
universeSize = 13000
import multiprocessing as mp
pool = mp.Pool(mp.cpu_count())
for i, row in range(0, gq_result_df.shape[0]):
pval = [pool.apply(fisher_test, args = (row["module_genes"],
gq_result_df.loc[j,"module_genes"], universeSize)) for j in range(i+1, gq_result_df.shape[0])]
#print("pval:", pval)
for j in range(i +1, fish_pval_mat.shape[0]):
pval_matrix[i, j] = pval[j -i -1]
pool.close()
pool.join()
运行外循环119次时的计算时间
如何优化并行化代码以减少时间?提前感谢您的问题是使用了
Pool.apply()
,因为这是一个阻塞调用。因此,您的执行不是并行的,而是顺序的。Pool.apply()阻塞,直到结果可用,这只是您提到的嵌套循环的另一个实现。您将一个区块提交给子流程,等待它被处理,然后再提交另一个区块,而不是一次提交所有区块
我不熟悉这个特定的算法,也不确定你是否可以并行化它——即,要处理的块是独立的还是之前的块的结果会影响连续的任务,在这种情况下,这不会并行化
如果它确实并行化,您可以尝试使用
apply\u async()
。如果您这样做,那么界面会发生一些变化,因为您的pval
不再是一个结果列表,而是一个AsyncResult
对象列表,您需要遍历这些对象并get()
从您的工作人员那里获得实际结果。fisher_test来自哪里?是您自己定义的,还是导入的?我自己定义的@Jamesyes,apply\u async()
可以正常工作。但是,apply_async()
的一个警告是,结果中的数字顺序混乱,表明进程没有按照启动顺序完成。不,它不能保证-这或多或少是并行处理的重点。如果您对顺序感兴趣,可以将索引作为apply_async中的参数发送给工作人员,然后在结果集中返回未修改的索引。在这种情况下,更简单的是,pval列表的形成顺序就是提交顺序。如果您在for循环中枚举该值以获得结果,那么如果足够的话,您至少可以免费获得序号。