当前位置: 首页 > news >正文

model训练中python基本数据类型的保存输出

在Python中,如果希望透明地存储对象,而不丢失其身份和类型等信息,则需要某种形式的对象序列化,这是一个将任意复杂的对象转成对象的文本和二进制表示的过程。同样,必须能够将对象经过序列化后的形式恢复到原来的对象。这种序列化的过程称为pickle,可以将对象pickle成字符串、磁盘上的文件或者任何类似于文件的对象;反序列化的过程就是将这些字符串、文件或任何类似于文件的对象unpickle成原来的对象。

主要是字符串、列表、元组与集合等,这一部分数据相比字典格式的数据比较简单(非复合数据,字典一般都是复合型数据,里面可以再嵌套前面所提到的这些数据格式)。

下面以保存字典数据类型数据为例进行解释,

一,保存为json

在 Python 中,json 模块提供了 dumpdumpsloadloads 四个函数,它们用于处理 JSON 数据的序列化和反序列化。

一、dumpdumps

1. dump
  • 用途:将 Python 对象序列化为 JSON 格式的字节流,并将其写入文件或类文件对象。
  • 参数
    • 第一个参数是要序列化的 Python 对象。
    • 第二个参数是文件或类文件对象。
  • 特点:直接将序列化后的数据写入文件,适合将数据持久化到文件系统中。
示例
import json# 创建一个 Python 字典
data = {"name": "Alice", "age": 25, "city": "New York"}# 将数据序列化并写入文件
with open("data.json", "w") as file:json.dump(data, file)# 文件 data.json 中的内容将是:
# {
#     "name": "Alice",
#     "age": 25,
#     "city": "New York"
# }

2. dumps
  • 用途:将 Python 对象序列化为 JSON 格式的字符串。
  • 参数:只接受一个参数,即要序列化的 Python 对象。
  • 特点:返回一个字符串,适合在程序中进行传递、存储或其他处理。
示例
import json# 创建一个 Python 字典
data = {"name": "Bob", "age": 30, "city": "Los Angeles"}# 将数据序列化为字符串
json_str = json.dumps(data)# 打印字符串
print(json_str)
# 输出:
# {"name": "Bob", "age": 30, "city": "Los Angeles"}# 可以将这个字符串用于其他操作,例如发送到网络、存储到内存等

详细比较,我们可以发现:

dumps是将python对象(比如说此处的dict)转换为json格式的str

而dump是将该对象转换为了json格式的字节流,并将其写入类文件对象

也就是说dump比dumps多了和文件操作结合起来的步骤

二、loadloads

1. load
  • 用途:从文件中读取 JSON 数据并将其解析为 Python 对象。
  • 参数:接受一个文件对象作为参数。
  • 特点:直接从文件中读取数据并解析,适合处理存储在文件中的 JSON 数据。
示例

此处我的示例数据如下:

import json# 假设有一个文件 data.json,内容如下:
# {
#     "name": "Charlie",
#     "age": 35,
#     "city": "Chicago"
# }# 从文件中读取 JSON 数据
with open("data.json", "r") as file:data = json.load(file)# 打印解析后的 Python 对象
print(data)
# 输出:
# {'name': 'Charlie', 'age': 35, 'city': 'Chicago'}

2. loads
  • 用途:将 JSON 格式的字符串解析为 Python 对象。
  • 参数:接受一个包含 JSON 数据的字符串作为参数。
  • 特点:从字符串中解析数据,适合处理从网络、内存等地方获取的 JSON 字符串。
示例
import json# JSON 字符串
json_str = '{"name": "David", "age": 40, "city": "Houston"}'# 将 JSON 字符串解析为 Python 对象
data = json.loads(json_str)# 打印解析后的 Python 对象
print(data)
# 输出:
# {'name': 'David', 'age': 40, 'city': 'Houston'}

三、总结

  • dump** 和 **dumps
    • dump 是将数据序列化后直接写入文件。
    • dumps 是将数据序列化为字符串,返回字符串。
  • load** 和 **loads
    • load 是从文件中读取 JSON 数据并解析为 Python 对象。
    • loads 是从字符串中解析 JSON 数据为 Python 对象。

简单来说:

  • 如果你需要将数据写入文件,就用 dump
  • 如果你需要将数据转换为字符串,就用 dumps
  • 如果你需要从文件中读取 JSON 数据,就用 load
  • 如果你需要从字符串中解析 JSON 数据,就用 loads
json的dump和dumps的区别
dumps是将dict转化成str格式,loads是将str转化成dict格式。
dump和load也是类似的功能,只是与文件操作结合起来了。简单理解就是dump和load需要一个类似于文件指针的参数(并不是真的指针,可称之为类文件对象),可以与文件操作结合

总之,带s的dumps和loads都是涉及到str字符串,

不带s的dump和load都是直接字节流的文件操作

二,保存为pkl文件

一般使用joblib模块或者是pickle模块,也就是我们在机器学习保存最优model结果的同样操作。

python中的json模块(前面一种方法)和pickle、joblib模块,实际上都是用于数据的序列化和反序列化,所提供的方法也无非是一致的:dumps、dump以及loads、load。

总得来说:

  • dumps(obs):将对象序列化为str
  • dump(obj,fp):将对象序列化为str,并存入文件中
  • loads(s):将(序列化之后的)字符串反序列化为Python对象
  • load(fp):将文件中的(序列化后的)字符串反序列化为Python对象

所以操作逻辑上其实json和pkl是一样的,细节上有点差异:

  • 通用性:

json序列化后的字符串是通用的格式(普通的字符串)在不同的平台和语言都可以识别,而pickle序列化后的字符串只有Python可以识别(Python专用序列化模块)

  • 处理的数据类型:

json能序列化的对象只是Python中基础数据类型,而pickle能序列化Python中所有的数据类型(划重点,是所有数据类型,所以实际上所有中间变量或者是函数返回结果,都可以直接用pkl格式文件接住并复原)

  • 处理后的数据类型:

json序列化后的字符串是文本类型(记事本打开文件后或者print打印后,你也能看懂其中的内容),而pickle序列化后的字符串是二进制流数据(记事本打开后或者print打印后就完全看不懂里面的内容了)。所以在进行文件操作时注意使用的是哪个模块,是否需要以b的格式打开。

总之,如果是保存为pkl文件的话,一般而言要么使用joblib,或者是pickle模块。

实际使用的时候,个人推荐joblib(至少我一般内存缓存,或存储model结果的大型数组的时候,还是joblib使用的多),

相比pickle,joblib会

  • 内存缓存:自动缓存函数的输出结果,避免重复计算。
  • 高效存储:特别优化用于存储大型数组,使用joblib进行数据序列化和反序列化比Python标准的pickle更快。
  • 并行计算支持:简化了并行计算的实现,能够轻松地在Python代码中实现多核处理。
特性PickleJoblib
序列化算法Python内置序列化基于pickle,针对科学计算优化
numpy数组处理标准序列化高效处理,使用内存映射
压缩支持需要额外模块(gzip等)内置压缩支持
大文件处理内存占用较高内存友好,支持lazy loading
并行安全不支持支持并行读写
兼容性标准Python需要安装scikit-learn

比如说我手头上有这么一个字典数据:

如果我想要保存,使用pickle的话:

import pickle
# 保存为pickle文件
with open("dict1.pkl","wb") as f:pickle.dump(dict1,f)# 读取pkl文件
with open("dict1.pkl","rb") as f:dict1_new = pickle.load(f)
dict1_new

同理使用joblib也是一样的:

import joblib
# 保存为pkl文件with open("dict1_new.pkl","wb") as f:joblib.dump(dict1_new,f)# 读取pkl文件
with open("dict1_new.pkl","rb") as f:dict1_new = joblib.load(f)dict1_new

joblib还可以使用压缩参数,常用的压缩格式就是:level 3

另外在实际使用时joblib和pickle还是有点区别的:

import joblib
# 直接保存为pkl文件
joblib.dump(dict1,"dict1_new2.pkl")dict2_new = joblib.load("dict1_new2.pkl")dict2_new

这里应该就很明显了,pickle在dump还是load,都需要句柄,但是joblib可以直接处理。

如何理解句柄上的差异,在下面的小结中展示

三,小结

1,json和joblib/pickle存储格式的差异

为什么在json保存中使用dump或load,open中只要使用w或r模式就可以了,但是在joblib或者pickle中得使用wb或rb?

JSON存储格式:

  • 文本格式:JSON以纯文本形式存储数据
  • 人类可读:可以用任何文本编辑器打开查看
  • 编码方式:使用字符编码(如UTF-8)

Pickle/Joblib存储格式:

  • 二进制格式:以字节流形式存储数据
  • 机器可读:包含Python对象的完整序列化信息
  • 编码方式:直接的字节表示
# 演示不同文件模式的区别
import json
import pickle
import joblib# 测试数据
test_data = {"name": "test", "values": [1, 2, 3]}# 1. JSON - 文本模式
print("=== JSON文本模式 ===")
# 保存 - 使用文本模式 'w'
with open('test_json.json', 'w') as f:json.dump(test_data, f)# 读取 - 使用文本模式 'r'  
with open('test_json.json', 'r') as f:data = json.load(f)
print(f"JSON读取结果: {data}")# 查看JSON文件内容(文本格式)
with open('test_json.json', 'r') as f:content = f.read()
print(f"JSON文件内容: {content}")# 2. Pickle - 二进制模式
print("\n=== Pickle二进制模式 ===")
# 保存 - 必须使用二进制模式 'wb'
with open('test_pickle.pkl', 'wb') as f:pickle.dump(test_data, f)# 读取 - 必须使用二进制模式 'rb'
with open('test_pickle.pkl', 'rb') as f:data = pickle.load(f)
print(f"Pickle读取结果: {data}")# 查看Pickle文件内容(二进制格式,不可读)
with open('test_pickle.pkl', 'rb') as f:content = f.read()
print(f"Pickle文件内容(前50字节): {content[:50]}")

JSON必须使用文本模式的原因:

import jsondata = {"test": "value"}# 正确方式 - 文本模式
with open('correct.json', 'w') as f:json.dump(data, f)# 错误方式 - 二进制模式会报错
try:with open('wrong.json', 'wb') as f:json.dump(data, f)  # 这会报错
except TypeError as e:print(f"JSON使用二进制模式的错误: {e}")# 错误信息: a bytes-like object is required, not 'str'

Pickle/Joblib必须使用二进制模式的原因:

import pickledata = {"test": "value"}# 正确方式 - 二进制模式
with open('correct.pkl', 'wb') as f:pickle.dump(data, f)# 错误方式 - 文本模式会报错
try:with open('wrong.pkl', 'w') as f:pickle.dump(data, f)  # 这会报错
except TypeError as e:print(f"Pickle使用文本模式的错误: {e}")# 错误信息: write() argument must be str, not bytes

2,关于文件句柄的使用

JSON - 必须使用文件句柄

import jsondata = {"test": "data"}# JSON必须通过文件句柄操作
# 这是因为json.dump/load设计为接受文件对象参数# 保存方式1:使用文件句柄
with open('data.json', 'w') as f:json.dump(data, f)# 保存方式2:直接转换为字符串再写入
json_string = json.dumps(data)  # 转换为JSON字符串
with open('data2.json', 'w') as f:f.write(json_string)# 读取方式1:使用文件句柄
with open('data.json', 'r') as f:loaded_data = json.load(f)# 读取方式2:先读取字符串再解析
with open('data.json', 'r') as f:json_string = f.read()
loaded_data = json.loads(json_string)  # 从字符串解析print(f"JSON加载的数据: {loaded_data}")

Pickle/Joblib - 支持直接文件路径否?

import pickle
import joblibdata = {"test": "data"}# Pickle的两种使用方式
print("=== Pickle使用方式 ===")# 方式1:使用文件句柄(传统方式)
with open('data_pickle_handle.pkl', 'wb') as f:pickle.dump(data, f)with open('data_pickle_handle.pkl', 'rb') as f:loaded_data = pickle.load(f)
print(f"Pickle句柄方式: {loaded_data}")# 方式2:pickle不支持直接文件路径
pickle.dump(data, 'file.pkl')  # 这样是错误的

# Joblib的两种使用方式
print("\n=== Joblib使用方式 ===")# 方式1:直接使用文件路径(推荐)
joblib.dump(data, 'data_joblib_direct.pkl')
loaded_data = joblib.load('data_joblib_direct.pkl')
print(f"Joblib直接路径方式: {loaded_data}")# 方式2:使用文件句柄
with open('data_joblib_handle.pkl', 'wb') as f:joblib.dump(data, f)with open('data_joblib_handle.pkl', 'rb') as f:loaded_data = joblib.load(f)
print(f"Joblib句柄方式: {loaded_data}")

所以在实际使用的时候,比如说model训练的时候,对于要保存的model,以及要保存的重要数据变量(比如某个dict),

我最常用的其实就是joblib,而且不使用文件句柄,直接dump、直接load

http://www.lqws.cn/news/539533.html

相关文章:

  • 爬虫006----Scrapy框架
  • 2025-6-27-C++ 学习 模拟与高精度(7)
  • Kotlin中协程挂起函数的本质
  • SpringBoot -- 整合Junit
  • 分布式session解决方案
  • 笔记:使用EasyExcel导入csv文件出现编码问题,导致导入数据全为null的解决方法
  • Apache Kafka 面试应答指南
  • 那些不应该的优化
  • html配置rem实现页面自适应
  • Linux:从后往前查看日志命令
  • 编译原理---文法和语法分析
  • 基于全局构建版本和ES模块构建版本的vue3 快速上手
  • LLM驱动开发:正在重塑软件工程的下一场革命
  • Maven生命周期与阶段扩展深度解析
  • GO 语言学习 之 语句块
  • vscode把less文件生成css文件配置,设置生成自定义文件名称和路径
  • FlutterPackages中的animations库升级适配Flutter3.27
  • Ubuntu18.04/Mysql 5.7 建立主备模式Mysql集群
  • 华为云Flexus+DeepSeek征文|Dify平台开发搭建口腔牙科24小时在线问诊系统(AI知识库系统)
  • C++学习笔记
  • 16.3 Docker生产级部署:网络与存储高效配置实战,保障99.95%可用性
  • 387. 字符串中的第一个唯一字符
  • uni-app uts 插件 android 端 科大讯飞离线语音合成最新版
  • 修改表中满足特定条件的字段值
  • elementUI轮播图组件el-carousel适配移动端大小(图片加载好后根据大小适配)
  • 抽样分布与参数估计细节
  • 如何在安卓设备上发送长视频:6 种可行的解决方案
  • GitHub Actions与AWS OIDC实现安全的ECR/ECS自动化部署
  • 从输入到路径:AI赋能的地图语义解析与可视化探索之旅
  • 远程办公与协作新趋势:从远程桌面、VDI到边缘计算,打造高效、安全的混合办公环境