Python 迭代中每行的并行处理
我有Python 迭代中每行的并行处理,python,pandas,multiprocessing,Python,Pandas,Multiprocessing,我有df_水果,这是水果的数据帧 index name 1 apple 2 banana 3 strawberry 并且,它的市场价格在mysql数据库中,如下所示 category market price apple A 1.0 apple B 1.5 banana A 1.2 banana
df_水果
,这是水果的数据帧
index name
1 apple
2 banana
3 strawberry
并且,它的市场价格在mysql数据库中,如下所示
category market price
apple A 1.0
apple B 1.5
banana A 1.2
banana A 3.0
apple C 1.8
strawberry B 2.7
...
在df_fruits
的迭代过程中,我想做一些处理
下面的代码是非并行版本
def process(fruit):
# make DB connection
# fetch the prices of fruit from database
# do some processing with fetched data, which takes a long time
# insert the result into DB
# close DB connection
for idx, f in df_fruits.iterrows():
process(f)
我想做的是对df_fiults
中的每一行并行处理,因为df_fiults
有很多行,并且市场价格的表大小相当大(获取数据需要很长时间)
如您所见,行之间的执行顺序无关紧要,并且没有共享数据
在df_fruits
中的迭代中,我不知道在哪里可以找到'pool.map()。我是否需要在并行执行之前分割行,并将块分配给每个进程?(如果是这样,则比其他进程更早完成其工作的进程将处于空闲状态?)
我研究过pandarallel,但我不能使用它(我的操作系统是windows)
任何帮助都将不胜感激。是的,这是可能的,尽管熊猫图书馆并没有直接提供
也许你可以尝试这样做:
def do_parallel_stuff_on_dataframe(df, fn_to_execute, num_cores):
# create a pool for multiprocessing
pool = Pool(num_cores)
# split your dataframe to execute on these pools
splitted_df = np.array_split(df, num_cores)
# execute in parallel:
split_df_results = pool.map(fn_to_execute, splitted_df)
#combine your results
df = pd.concat(split_df_results)
pool.close()
pool.join()
return df
您可能可以执行以下操作:
with Pool() as pool:
# create an iterator that just gives you the fruit and not the idex
rows = (f for _, f in df_fruits.iterrows())
pool.imap(process, rows)
如果您不关心结果,或者愿意以任何顺序获得结果,或者不关心结果,则可能需要使用map以外的其他池原语之一。根本不需要使用pandas
。您只需使用包中的池
Pool.map()
接受两个输入:一个函数和一个值列表
因此,您可以:
来自多处理导入池的
n=5#任意数量的螺纹
将池(n)作为p:
p、 映射(进程,df_水果['name'].值)
这将逐个遍历df_fruits
数据帧中的所有结果。请注意,这里没有返回结果,因为进程
函数旨在将结果写回数据库
如果您想在每一行中拥有多个列,则可以更改<代码> DFI-水果[[名称] ],值 >:
df_fruits[cols]。to_dict('records'))
这将提供一个字典作为预处理
的输入,例如:
{'name':'apple','index':1,…}
数据有多大?@Yash嗯,我不能确切地说,但仅仅获取市场价格有时需要几分钟的时间。问题不仅在于数据的大小,还在于数据库的结构差(这使得获取需要更长的时间)。谢谢您的回答。在process
函数中,我需要访问其他列值进行处理。虽然我只传递了df_fruits['name'],但我是否可以访问过程中的其他列?@W.Cointreau:不,您不能。但是,您可以使用df_fruits['name'].values
,而不是使用df_fruits[cols].values
(要考虑的列是cols
)。或者您可以简单地使用df_.values
。这将为您提供列表形式的值。通常使用字典比较容易,所以您可以尝试使用df\u fruits.to\u dict('records')
。由于process
函数有更多的参数,所以我也提到了。最后,我需要使用partial
比如func=partial(process,param1,param2…
,然后使用pool.map(func,df_.to_dict('records'))
。非常感谢!啊,我从来没有听说过imap
。我从这里找到了一些知识:。谢谢。实际上,我刚刚尝试了一个实验,map
似乎比imap
对100000个元素的快速操作要快。所有这些都允许迭代器作为参数。实验一下,看看哪一个对y最有效当然,我们不知道您是否需要处理的结果。好的,我会试试。我希望imap
可以比map
更快,因为在process
中获取数据是主要的瓶颈,而且每个作业都不会影响其他作业。当我尝试与几个工作人员一起使用map
时,他们中的一些人似乎在等待虽然他们不需要等待,但彼此都要完成。。。