具有多处理功能的两个数据帧之间的并行比较 [英] Parallelizing comparisons between two dataframes with multiprocessing
问题描述
我具有以下函数,该函数使我可以在两个数据帧( data
和 ref
)的行之间进行一些比较,并在返回两个行的索引时有一场比赛.
def get_gene(row):m = np.equal(row [0],ref.iloc [:,0] .values)&np.greater_equal(row [2],ref.iloc [:,2] .values)&np.less_equal(row [3],ref.iloc [:,3] .values)如果m.any()则返回ref.index [m],否则返回None
作为一个耗时的过程(对于 data
中的1.6M行,需要25分钟,而对于 ref
中的20K行,则需要25分钟),我试图通过并行化计算来加快速度.由于pandas本身不支持多处理,因此我使用了在SO上找到的这段代码,并且可以与我的函数 get_gene
正常工作.
def _apply_df(args):df,func,kwargs = args返回df.apply(func,** kwargs)def apply_by_multiprocessing(df,func,** kwargs):工人= kwargs.pop('工人')池= multiprocessing.Pool(进程=工人)结果= pool.map(_apply_df,[[np.array_split(df,worker)中d的((d,func,kwargs)]))pool.close()df = pd.concat(列表(结果))返回df
这使我节省了9分钟的计算时间.但是,如果我理解正确,那么这段代码会将我的数据帧 data
分解为4部分,并将每个数据帧发送到CPU的每个内核.因此,每个内核最终都要在40万行(来自 data
分成4个)和20K行( ref
)之间进行比较.
我实际上想要做的是根据一个列中的值拆分两个数据框,以便我只计算同一组"的数据框之间的比较:
-
data.get_group(['a'])
与ref.get_group(['a'])
-
data.get_group(['b'])
与ref.get_group(['b'])
-
data.get_group(['c'])
与ref.get_group(['c'])
-
等...
这将减少计算量. data
中的每一行只能与 ref
中的〜3K行匹配,而不是全部20K行.
因此,我尝试修改上面的代码,但无法使其正常工作.
def apply_get_gene(df,func,** kwargs):参考= pd.read_csv('genomic_positions.csv',index_col = 0)参考= reference.groupby(['Chr'])df = df.groupby(['Chr'])染色体= df.groups.keys()工人= multiprocessing.cpu_count()池= multiprocessing.Pool(进程=工人)args_list = [[df.get_group(chrom),func,kwargs,reference.get_group(chrom))用于染色体中的chrom]结果= pool.map(_apply_df,args_list)pool.close()pool.join()返回pd.concat(结果)def _apply_df(args):df,func,kwarg1,kwarg2 = args返回df.apply(func,** kwargs)def get_gene(row,ref):m = np.equal(row [0],ref.iloc [:,0] .values)&np.greater_equal(row [2],ref.iloc [:,2] .values)&np.less_equal(row [3],ref.iloc [:,3] .values)如果m.any()则返回ref.index [m],否则返回None
我很确定这与通过不同功能传递 * args
和 ** kwargs
的方式有关(因为在这种情况下,我有考虑到我想将分割后的 ref
数据帧与分割后的 data
数据帧一起传递.)我认为问题出在 _apply_df
函数之内.我以为我了解它的真正作用,但 df,func,kwargs = args
这行仍然困扰着我,我认为我无法正确修改它.
感谢所有建议!
看看 解决方案
Take a look at starmap()
:
starmap(func, iterable[, chunksize]) Like map() except that the elements of the iterable are expected to be iterables that are unpacked as arguments.
Hence an iterable of [(1,2), (3, 4)] results in [func(1,2), func(3,4)].
Which seems to be exactly what you need.
这篇关于具有多处理功能的两个数据帧之间的并行比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!