Python高效計算庫Joblib的入門教程
1. Joblib庫是什么?
Joblib 是一個用于在 Python 中進行高效計算的開源庫,提供了一些用于內(nèi)存映射和并行計算的工具,能大幅提高科學計算和數(shù)據(jù)分析的效率,特別適合于需要進行重復計算或大規(guī)模數(shù)據(jù)處理的任務。
Joblib 庫的常用關鍵功能包括對象高效序列化、函數(shù)值臨時緩存以及并行計算,能夠優(yōu)化數(shù)據(jù)處理流程。在Python中安裝 Joblib 庫也非常簡單,通過 pip 執(zhí)行以下命令即可:
pip install joblib
安裝完成后,執(zhí)行如下代碼,如果能輸出相應版本號,則說明已經(jīng)成功安裝。
import joblib print(joblib.__version__)
2. 核心功能介紹及演示
joblib 庫的主要功能體現(xiàn)在以下三方面:
- 高效序列化和反序列化:除特殊Python對象外,Joblib 庫能將數(shù)值對象高效序列化保存到本地,常常用來保存、加載數(shù)據(jù)對象和模型對象;
- 快速磁盤緩存:夠提供高效的磁盤緩存和延遲加載,可以將函數(shù)的返回值緩存到磁盤上以避免重復計算;
- 并行計算:能輕松將代碼任務分配到多核處理器上。
2.1 高效序列化和反序列化對象
類似于 pickle 庫,Joblib 庫提供了 dump 和 load 函數(shù),能夠高效地將大型數(shù)據(jù)對象(例如大型數(shù)組、機器學習模型等)保存到本地文件或從本地文件加載回來。Joblib 針對 numpy 數(shù)組進行了特定的優(yōu)化,基于殊序列化格式,相比于通用的序列化更加高效。
如下例子,對比了 pickle 庫和 Joblib 庫在保存和加載大規(guī)模數(shù)組上的效率。首先生成 ( 10000 , 10000 ) (10000,10000)(10000,10000) 的數(shù)組,兩個庫分別循環(huán)保存和加載數(shù)據(jù) 5 55 次,最終的平均處理時間如下(見注釋部分):
import numpy as np
import pickle, joblib, time
# 生成一個大型的 numpy 數(shù)組對象,例如 10000 x 10000 的數(shù)組
large_array = np.random.rand(10000, 10000)
# 循環(huán)5次
n = 5
# 平均處理時間 2.54s
for i in range(n):
with open(f'pickle_data_{i}.pkl', 'wb') as f:
pickle.dump(large_array, f)
# 平均處理時間 0.72s
for i in range(n):
with open(f'pickle_data_{i}.pkl', 'rb') as f:
load_large_array = pickle.load(f)
# 平均處理時間 2.16s
for i in range(n):
joblib.dump(large_array, f'joblib_data_{i}.joblib')
# 平均處理時間 0.04s
for i in range(n):
load2_large_array = joblib.load(f'joblib_data_{i}.joblib')
相比于 pickle 庫加載 .pkl 文件,Joblib 庫加載 .joblib 文件的平均效率極高,保存文件的效率也有一定的優(yōu)勢,此外,Joblib 庫的接口更加易用,因此在處理含大量數(shù)據(jù)的任務時常常用來代替 pickle 庫。
這種保存再加載的方式,常用在將訓練好的模型或計算的數(shù)據(jù)集保存后分發(fā)給其他用戶,還常常用于大規(guī)模數(shù)據(jù)的深拷貝(相比于直接深拷貝,保存后加載的方式常常更快)等場景中。
2.2 快速磁盤緩存
Joblib 庫的另一核心功能是能將函數(shù)的計算返回值快速緩存到磁盤上(記憶模式),當再次調(diào)用該函數(shù)時,如果函數(shù)的輸入?yún)?shù)沒有改變,則 Joblib 直接從緩存中加載結(jié)果而不是重新計算。
如下例子,通過定義緩存目錄,以及創(chuàng)建緩存器,添加指定裝飾器后,當我們運行第一次函數(shù)時,會將函數(shù)計算結(jié)果緩存到磁盤,再次調(diào)用函數(shù)時,如果輸入?yún)?shù)相同,則從磁盤調(diào)出相應的計算結(jié)果,避免重復計算。當然了,很自然的一個想法是,為什么不把函數(shù)的計算結(jié)果保存為哈希表,傳入?yún)?shù)為鍵,計算結(jié)果為值,當然也是可行的,但這會極大占用內(nèi)存,而 Joblib 是將原本應在內(nèi)存上的計算結(jié)果緩存到磁盤,且緩存和調(diào)用的處理非???。
from joblib import Memory
import time
cachedir = './my_cache' # 定義緩存目錄
memory = Memory(cachedir, verbose=0)
@memory.cache
def expensive_computation(a, b):
print("Computing expensive_computation...")
sum_ = 0
for i in range(1000000):
sum_ += a * b / 10 + a / b
return sum_
# 第一次調(diào)用,將計算并緩存結(jié)果
result = expensive_computation(20, 3)
# 0.0967 s
# 第二次調(diào)用,將直接從緩存加載結(jié)果
result = expensive_computation(20, 3)
# 0.000997 s
上述代碼的裝飾器可以理解為將函數(shù) expensive_computation 作為參數(shù)傳入 memory.cache() 方法當中,上述寫法等價于 memory.cache(expensive_computation())。
顯然,對于有大量重復計算的任務,該庫能極大地提高處理效率。值得注意的是,上述定義的函數(shù)中,存在打印語句 print(...),當首次執(zhí)行函數(shù)時,會執(zhí)行該打印語句,而函數(shù)是重復執(zhí)行的,則會直接從緩存中繼承曾經(jīng)的計算結(jié)果,而不會經(jīng)過中間具體的計算邏輯,也就不會打印相關語句。
2.3 并行計算
Joblib 的最核心的功能應該是提供了高級的(簡單易用)并行化工具,能夠使我們輕松地將計算任務分配到多個 CPU 核心上執(zhí)行。
如下所示,當我們有多個獨立的任務需要執(zhí)行,可以通過 Joblib 的 Parallel 和 delayed 功能并行處理這些任務,從而節(jié)省時間。
from joblib import Parallel, delayed
import numpy as np
def process(i):
data = np.random.rand(1000, 1000)
# 普通的循環(huán)計算
# 5.798 s
for i in range(1000):
process(i)
# Joblib 的并行計算
# 3.237 s
Parallel(n_jobs=4)(delayed(process)(i) for i in range(1000))
上述式子在,n_jobs 定義了線程數(shù),若n_jobs=-1,則啟用所有可用的 CPU 核心;delayed() 中傳入任務(函數(shù))名,而后的 (i) 為任務分配傳入?yún)?shù),在 Joblib 的并行計算下,執(zhí)行 1000 10001000 次任務 process() 的時間為 3.237 s 3.237s3.237s,而循環(huán)依次執(zhí)行的時間為 5.798 s 5.798s5.798s。
隨著任務的計算復雜度增大、獨立任務數(shù)增多,并行計算的優(yōu)勢會逐漸明顯,但相對于我們開的并行任務數(shù),這種優(yōu)勢有時并不那么顯著。原因在于,默認情況下,joblib.Parallel 是啟動單獨的Python工作進程,以便在分散的CPU上同時執(zhí)行任務,但由于輸入和輸出數(shù)據(jù)需要在隊列中序列化以便同工作進程進行通信,可能會導致大量開銷。因此,小規(guī)模任務下,Joblib 的并行計算效率可能較低。
到此這篇關于Python高效計算庫Joblib的入門教程的文章就介紹到這了,更多相關Python高效計算庫Joblib內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python編寫繪圖系統(tǒng)之從文本文件導入數(shù)據(jù)并繪圖
這篇文章主要為大家詳細介紹了Python如何編寫一個繪圖系統(tǒng),可以實現(xiàn)從文本文件導入數(shù)據(jù)并繪圖,文中的示例代碼講解詳細,感興趣的可以了解一下2023-08-08
Centos 升級到python3后pip 無法使用的解決方法
今天小編就為大家分享一篇Centos 升級到python3后pip 無法使用的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06

