pandas模块高性能使用方法总结
pandas处理起来大批量数据是很方便的,本文主要是根据自己的工作经验总结一下pandas里不同循环方法的优劣
import pandas as pd
import numpy as np
初级:for循环
#for 循环主要是把df表格拆分成一行一行的遍历主要有3种方法
df1 = pd.DataFrame(
{'a':list(range(0,10)),
'b':list(range(10,20)),
'c':list(range(20,30))}
)
for index,row in df1.iterrows():
index
row
for tup in df1.itertuples():
tup
#这两种循环方式和普通的python循环可迭代对象的方法没什么区别,只不过得到的数据类型是pandas相关的数据类型
#该种方法运行速度最慢,一般不建议使用
中级:apply
#除了apply还有map,agg等方法
#apply方法是针对pandas的数据结构优化过的,使用方式最为灵活,apply的函数可以是系统自带的聚合函数,或是简单的lambda函数,
#也可以是复杂的自定义函数,具体的使用方法不多做赘述
#当需要对数据分组然后运用自定义函数时可以先写成for循环的形式,方便调试逻辑,当逻辑测试没问题之后,再把循环逻辑单独写到一个函数里,
#简单举例
def func(df,x):
return df+x
res = df1.groupby('a').apply(func,1)
#func可以继续再调用函数,可以无限套娃
#apply的优点还是很明显的,如果被调用的函数不是很复杂或则数据量不大情况下
#如果一个df的分组有上百万数据,而且每个分组的函数又调用了大量其他的函数进行计算密集型的操作,
#此时单纯的使用apply已经不能够满足性能要求了,因为你的计算是串行的,至于为什么请自行搜索GIL全局解释器锁
高级:多进程
#为啥不开多线程要开多进程,在python中,计算密集型的任务开了多线程没啥效果,具体原因还请自行搜索GIL全局解释器锁
#回到业务情景,数据量大,计算密集,此时需要让多个cpu工作起来同时计算
#下面简单介绍3中并行计算的方式
#3.1使用multiprocessing.Pool模块,不建议使用
from multiprocessing import Pool
df_parts = np.array_split(df,8)
with Pool(process=8,initializer=inti_func,initargs=(args,)) as pool:
result_df = pool.map(func,df_parts)
res_df = pd.concat(result_df)
#3.2使用concurrent.futures.ProcessPoolExecutor模块,建议使用
from concurrent.futures import ProcessPoolExecutor
res = []
def _callback():
res.append(r.result())
pool = ProcessPoolExecutor(8)
for task in task_lists:
res_df = pool.submit(func,params).add_done_callback(_callback)
pool.shutdown(wait=True)
#3.3使用joblib模块,不建议使用
from joblib import Parallel,delayed
df_group = df.groupby('id')
result = Parallel(n_jobs=8)(delayed(func)(id,df_group) for id,p_df in df_group)
result_df = pd.concat(result)
#这些模块开启多进程的具体方法见后续更新