背景:
pandas处理大量排序计算,在单进程情况下性能特别慢
在接到项目需求的时候,因为存在大量的计算过程,需要调用多个CPU,所以优先考虑多进程实现。
开发中遇到的问题:
进程间通信一直是一个比较棘手的问题,刚开始我尝试使用自带的manager()方法,不过怎么尝试都不成功,毕竟manager只支持他们提供的那几个对象,比如queue、list、dict等,但是现在我需要将df对象传进去参与计算,这三个
df1 = df[['comcode', 'enddate', 'dataflag', 'finducode']]
df2 = df[['comcode', 'enddate', 'dataflag', 'sinducode']]
df3 = df[['comcode', 'enddate', 'dataflag', 'tinducode']]
不过直接将值传进去肯定是线程不安全的,manager提供的那些对象也是保证线程安全的情况下,因为无法保证线程安全,现在显然不可以直接将对象传递进去。
解决方法:
不可以直接传进去,只能够通过一个线程安全的去接收数据了,可以将线程安全的对象传递进去获取计算的数据,等计算完成之后再将获取的数据进行解析。可以使用manager提供的List,不过我使用的返回,将df1、df2、df3封装到[]中返回,再将返回值用List进行接收,也是可以保证其线程安全性,最后将封装的数据进行解析就行。
jobs = []
# 循环计算各指标分组内排名
for index_name in df.columns.values:
p1 = pool.apply_async(func=exerank, args=(index_name, df, df1, df2, df3,))
jobs.append(p1)
# exerank(index_name, df, df1, df2, df3)
pool.close()
pool.join()
result_ = [j.get() for j in jobs]
for result_list in result_:
if result_list != 'nan':
df1 = pd.merge(df1, result_list[0], on=['comcode', 'enddate', 'dataflag', 'finducode'])
df2 = pd.merge(df2, result_list[1], on=['comcode', 'enddate', 'dataflag', 'sinducode'])
df3 = pd.merge(df3, result_list[2], on=['comcode', 'enddate', 'dataflag', 'tinducode'])
当然也可以使用提供的List传进去接收值,不过我觉得前者可以保证线程安全得情况下使用更严谨的后者反而复杂了,后者可能在更复杂的情况下使用。