Python高效计算库Joblib的入门教程

 更新时间:2025年01月08日 11:28:58   作者:Lins号丹  
Joblib库是一个用于在Python中进行高效计算的开源库,提供内存映射和并行计算工具,本文就来介绍一下Joblib库的使用,具有一定的参考价值,感兴趣的可以了解一下

1. Joblib库是什么?

Joblib 是一个用于在 Python 中进行高效计算的开源库,提供了一些用于内存映射和并行计算的工具,能大幅提高科学计算和数据分析的效率,特别适合于需要进行重复计算或大规模数据处理的任务。

Joblib 库的常用关键功能包括对象高效序列化、函数值临时缓存以及并行计算,能够优化数据处理流程。在Python中安装 Joblib 库也非常简单,通过 pip 执行以下命令即可:

pip install joblib

安装完成后,执行如下代码,如果能输出相应版本号,则说明已经成功安装。

import joblib
print(joblib.__version__)

2. 核心功能介绍及演示

joblib 库的主要功能体现在以下三方面:

  • 高效序列化和反序列化:除特殊Python对象外,Joblib 库能将数值对象高效序列化保存到本地,常常用来保存、加载数据对象和模型对象;
  • 快速磁盘缓存:够提供高效的磁盘缓存和延迟加载,可以将函数的返回值缓存到磁盘上以避免重复计算;
  • 并行计算:能轻松将代码任务分配到多核处理器上。

2.1 高效序列化和反序列化对象

类似于 pickle 库,Joblib 库提供了 dump 和 load 函数,能够高效地将大型数据对象(例如大型数组、机器学习模型等)保存到本地文件或从本地文件加载回来。Joblib 针对 numpy 数组进行了特定的优化,基于殊序列化格式,相比于通用的序列化更加高效。

如下例子,对比了 pickle 库和 Joblib 库在保存和加载大规模数组上的效率。首先生成 ( 10000 , 10000 ) (10000,10000)(10000,10000) 的数组,两个库分别循环保存和加载数据 5 55 次,最终的平均处理时间如下(见注释部分):

import numpy as np
import pickle, joblib, time

# 生成一个大型的 numpy 数组对象,例如 10000 x 10000 的数组
large_array = np.random.rand(10000, 10000)

# 循环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 文件的平均效率极高,保存文件的效率也有一定的优势,此外,Joblib 库的接口更加易用,因此在处理含大量数据的任务时常常用来代替 pickle 库。

这种保存再加载的方式,常用在将训练好的模型或计算的数据集保存后分发给其他用户,还常常用于大规模数据的深拷贝(相比于直接深拷贝,保存后加载的方式常常更快)等场景中。

2.2 快速磁盘缓存

Joblib 库的另一核心功能是能将函数的计算返回值快速缓存到磁盘上(记忆模式),当再次调用该函数时,如果函数的输入参数没有改变,则 Joblib 直接从缓存中加载结果而不是重新计算。

如下例子,通过定义缓存目录,以及创建缓存器,添加指定装饰器后,当我们运行第一次函数时,会将函数计算结果缓存到磁盘,再次调用函数时,如果输入参数相同,则从磁盘调出相应的计算结果,避免重复计算。当然了,很自然的一个想法是,为什么不把函数的计算结果保存为哈希表,传入参数为键,计算结果为值,当然也是可行的,但这会极大占用内存,而 Joblib 是将原本应在内存上的计算结果缓存到磁盘,且缓存和调用的处理非常快。

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_

# 第一次调用,将计算并缓存结果
result = expensive_computation(20, 3)
# 0.0967 s

# 第二次调用,将直接从缓存加载结果
result = expensive_computation(20, 3)
# 0.000997 s

上述代码的装饰器可以理解为将函数 expensive_computation 作为参数传入 memory.cache() 方法当中,上述写法等价于 memory.cache(expensive_computation())。

显然,对于有大量重复计算的任务,该库能极大地提高处理效率。值得注意的是,上述定义的函数中,存在打印语句 print(...),当首次执行函数时,会执行该打印语句,而函数是重复执行的,则会直接从缓存中继承曾经的计算结果,而不会经过中间具体的计算逻辑,也就不会打印相关语句。

2.3 并行计算

Joblib 的最核心的功能应该是提供了高级的(简单易用)并行化工具,能够使我们轻松地将计算任务分配到多个 CPU 核心上执行。

如下所示,当我们有多个独立的任务需要执行,可以通过 Joblib 的 Parallel 和 delayed 功能并行处理这些任务,从而节省时间。

from joblib import Parallel, delayed
import numpy as np

def process(i):
    data = np.random.rand(1000, 1000)

# 普通的循环计算
# 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 定义了线程数,若n_jobs=-1,则启用所有可用的 CPU 核心;delayed() 中传入任务(函数)名,而后的 (i) 为任务分配传入参数,在 Joblib 的并行计算下,执行 1000 10001000 次任务 process() 的时间为 3.237 s 3.237s3.237s,而循环依次执行的时间为 5.798 s 5.798s5.798s。

随着任务的计算复杂度增大、独立任务数增多,并行计算的优势会逐渐明显,但相对于我们开的并行任务数,这种优势有时并不那么显著。原因在于,默认情况下,joblib.Parallel 是启动单独的Python工作进程,以便在分散的CPU上同时执行任务,但由于输入和输出数据需要在队列中序列化以便同工作进程进行通信,可能会导致大量开销。因此,小规模任务下,Joblib 的并行计算效率可能较低。

到此这篇关于Python高效计算库Joblib的入门教程的文章就介绍到这了,更多相关Python高效计算库Joblib内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Flask配置Cors跨域的实现

    Flask配置Cors跨域的实现

    这篇文章主要介绍了Flask配置Cors跨域的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Selenium chrome配置代理Python版的方法

    Selenium chrome配置代理Python版的方法

    这篇文章主要介绍了Selenium chrome配置代理Python版的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Python模拟三级菜单效果

    Python模拟三级菜单效果

    这篇文章主要为大家详细介绍了Python模拟三级菜单效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Python编写绘图系统之从文本文件导入数据并绘图

    Python编写绘图系统之从文本文件导入数据并绘图

    这篇文章主要为大家详细介绍了Python如何编写一个绘图系统,可以实现从文本文件导入数据并绘图,文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-08-08
  • Python生成九宫格图片的示例代码

    Python生成九宫格图片的示例代码

    这篇文章主要介绍了Python生成九宫格图片的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 使用Python实现LLM的模型迁移

    使用Python实现LLM的模型迁移

    在当今的人工智能领域,大型语言模型(LLM)如GPT、BERT等已经成为了研究和应用的热点,但其训练和部署成本高昂,且在不同领域或任务间的迁移能力有限,因此,如何有效地实现LLM的模型迁移,成为了一个重要的研究方向,本文将深入探讨如何使用Python实现LLM的模型迁
    2025-02-02
  • python飞机大战游戏实例讲解

    python飞机大战游戏实例讲解

    在本篇文章里小编给大家整理的是一篇关于python飞机大战游戏实例讲解,有兴趣的朋友们可以参考下。
    2020-12-12
  • 深入浅出Python中三个图像增强库的使用

    深入浅出Python中三个图像增强库的使用

    这篇文章主要带大家了解一下Python中三个图像增强库的使用:Imgaug、Albumentations和SOLT,文中通过示例进行了详细介绍,需要的可以参考一下
    2022-05-05
  • 详解Python命令行解析工具Argparse

    详解Python命令行解析工具Argparse

    这篇文章主要为大家详细介绍了Python命令行解析工具Argparse的相关资料,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • Centos 升级到python3后pip 无法使用的解决方法

    Centos 升级到python3后pip 无法使用的解决方法

    今天小编就为大家分享一篇Centos 升级到python3后pip 无法使用的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06

最新评论