【Python】Pandas groupby加速處理數(shù)據(jù)
在使用pandas的時候,經(jīng)常會用到groupby這個函數(shù)來對數(shù)據(jù)進行分組統(tǒng)計,同時可以使用 apply函數(shù)很方便的對分組之后的數(shù)據(jù)進行處理。
def data_process(x):# processreturn ...result?=?df.groupby('user_id').apply(data_process)
使用joblib進行加速
但是如果數(shù)據(jù)非常多的時候(比如幾千萬條數(shù)據(jù)),運行的效率是比較低的,因為這個時候只使用了一個CPU線程,所以當(dāng)數(shù)據(jù)非常多的時候,處理起來會很慢。這個時候CPU其他的核是空閑的,所以考慮使用joblib來多線程加速。
from joblib import Parallel, delayeddef data_process(x):# processreturn ...def applyParallel(dfGrouped, func):res = Parallel(n_jobs=4)(delayed(func)(group) for name, group in dfGrouped)return pd.concat(res)result?=?applyParallel(df.groupby('user_id'),?data_process)
使用pandarallel進行加速
除了使用joblib之外,還可以使用pandarallel進行加速,使用pandarallel無需編寫函數(shù),只需要提前初始化pandarallel即可。
from pandarallel import pandarallelpandarallel.initialize(progress_bar=True)# 可選參數(shù):# nb_workers:用于并行化的工作程序數(shù)。數(shù)值類型,如果未設(shè)置,則將使用所有可用的CPU。# progress_bar:如果設(shè)置為,則顯示進度條True。(False默認為布爾)# verbose:詳細級別(2默認為int )# 0-不顯示任何日志# 1-僅顯示警告日志# 2-顯示所有日志# use_memory_fs:(None默認為布爾)如果設(shè)置為None且內(nèi)存文件系統(tǒng)可用,Pandarallel將使用它在主進程和工作進程之間傳輸數(shù)據(jù)。# 如果內(nèi)存文件系統(tǒng)不可用,則Pandarallel將默認進行多處理數(shù)據(jù)傳輸(管道)。如果設(shè)置為True,則Pandarallel將使用內(nèi)存文件系統(tǒng)在主進程和工作進程之間傳輸數(shù)據(jù),SystemError如果內(nèi)存文件系統(tǒng)不可用,則會引發(fā)。# 如果設(shè)置為False,則Pandarallel將使用多處理數(shù)據(jù)傳輸(管道)在主進程和工作進程之間傳輸數(shù)據(jù)。def data_process(x):# processreturn ...result?=?df.groupby('user_id').parallel_apply(data_process)
需要說明的是,pandarallel目前只能在Linux和OS X上運行。使用內(nèi)存文件系統(tǒng)(參數(shù)use_memory_fs控制)可以減少主進程與工作進程之間的數(shù)據(jù)傳輸時間,尤其是對于大數(shù)據(jù)而言。僅當(dāng)目錄/dev/shm存在且用戶對其具有讀寫權(quán)限時,才認為內(nèi)存文件系統(tǒng)可用。基本上,內(nèi)存文件系統(tǒng)僅在某些Linux發(fā)行版(包括Ubuntu)上可用。
并行化具有成本(實例化新進程,通過共享內(nèi)存發(fā)送數(shù)據(jù)等),因此,只有在要進行并行化的計算量足夠高的情況下,并行化才有效。對于很少的數(shù)據(jù),使用并行化并不總是值得的。
參考:https://github.com/nalepae/pandaralle
往期精彩回顧 本站qq群554839127,加入微信群請掃碼:
