Python 并行处理数据帧

Python 并行处理数据帧,python,pandas,Python,Pandas,我有一个进程,需要处理数据帧的每一行,然后在每一行追加一个新值。这是一个大数据帧,每次处理一个数据帧需要几个小时 如果我有一个iterrow循环,它将每一行发送给一个函数,我可以并行处理以提高速度吗?行的结果不相关 基本上我的代码是这样的 for index, row in df.iterrows(): row['data'] = function[row] 有没有一种简单的方法来加快处理速度?在行上迭代不是一种好的做法,可以使用grouby/transform聚合等替代逻辑,但如果在最

我有一个进程,需要处理数据帧的每一行,然后在每一行追加一个新值。这是一个大数据帧,每次处理一个数据帧需要几个小时

如果我有一个iterrow循环,它将每一行发送给一个函数,我可以并行处理以提高速度吗?行的结果不相关

基本上我的代码是这样的

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

有没有一种简单的方法来加快处理速度?

在行上迭代不是一种好的做法,可以使用grouby/transform聚合等替代逻辑,但如果在最坏的情况下确实需要这样做,请按照答案进行操作。此外,您可能不需要在这里重新实现所有内容,您可以使用类似的库,它构建在pandas之上

但为了让大家了解一下,您可以将
多处理
Pool.map
)与
分块
结合使用。阅读chunk中的csv(或按照答案末尾所述制作Chuck)并将其映射到池中,在处理每个chunk时添加新行(或将它们添加到列表并制作新chunk)并从函数返回

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

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_((df长度)/(可用芯数-2))
eg
100000/14=round(7142.85)=7150行

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

与其使用
df.iterrows()
不如使用像
apply()
这样的向量化方法

.apply()是对列/行执行迭代的一种方法。它利用矢量化技术,将简单和复杂操作的执行速度提高了许多倍

查看本文以了解其区别


其他选择是查看
Dask
Vaex
,或者只是查看一下Dask。根据我的经验,如果您在数据帧中循环,您可能没有按熊猫的方式进行。正如@Jarad所说,您可能不想迭代。查看是否存在矢量化备选方案(不适用,取决于
函数
是否有更好的选项)--请参阅,并打开此选项。
df.apply(function, axis=1)