并行处理数据帧

时间:2020-10-14 22:33:45

标签: python pandas

我有一个过程,要求处理数据帧的每一行,然后将新值附加到每一行。这是一个很大的数据框,一次要花费几个小时来处理一个数据框。

如果我有一个将每一行发送到一个函数的迭代循环,我可以使我的处理并行化以提高速度吗?该行的结果不相关

基本上我的代码是这样的

for index, row in df.iterrows():
   row['data'] = function[row]

是否有一种简便的方法来加快处理速度?

2 个答案:

答案 0 :(得分:1)

虽然在行上进行迭代不是一个好习惯,并且可以使用grouby / transform聚合等替代逻辑,但是如果在最坏的情况下确实需要这样做,请遵循答案。另外,您可能无需在此处重新实现所有功能,而可以使用Dask之类的库,它们是基于熊猫构建的。

但是,仅出于想法的考虑,您可以将multiprocessingPool.map)与chunking结合使用。读取块中的csv(或按照答案末尾所述制作chuck)并将其映射到池中,在处理每个块时添加新行(或将它们添加到列表中并创建新块)并从函数中返回。 >

最后,在执行所有池时合并数据帧。

import pandas as pd
import numpy as np
import multiprocessing


def process_chunk(df_chunk):
        
        for index, row in df_chunk.reset_index(drop = True).iterrows():
                    #your logic for updating this chunk or making new chunk here
                         
                    print(row)
                    
                    print("index is " + str(index))
        #if you can added to same df_chunk, return it, else if you appended
        #rows to have list_of_rows, make a new df with them and return
        #pd.Dataframe(list_of_rows)  

        return df_chunk   


if __name__ == '__main__':
            #use all available cores , otherwise specify the number you want as an argument,
            #for example if you have 12 cores,  leave 1 or 2 for other things
            pool = multiprocessing.Pool(processes=10) 
            
            results = pool.map(process_chunk, [c for c in pd.read_csv("your_csv.csv", chunksize=7150)])
            pool.close()
            pool.join()
            
            #make new df by concatenating
            
            concatdf = pd.concat(results, axis=0, ignore_index=True)
            

注意:您可以通过相同的逻辑传递卡盘,而不是读取csv,以计算块大小,您可能需要类似round_of( (length of df) / (number of core available-2)),例如每个块100000/14 = round(7142.85) = 7150 rows

 results = pool.map(process_chunk,
        [df[c:c+chunk_size] for c in range(0,len(df),chunk_size])

答案 1 :(得分:0)

为什么不使用df.iterrows()之类的矢量化方法,而不是使用apply()

df.apply(function, axis=1)

.apply()是在列/行上执行迭代的熊猫方式。它利用矢量化技术的优势,可将简单和复杂操作的执行速度提高许多倍。

查看这篇Reference文章,以了解其不同之处。

其他选项正在使用DaskVaex或只是老式的Multiprocessing