LLM系列:1.python入门:15.JSON 数据处理与操作

张开发
2026/4/20 10:37:40 15 分钟阅读

分享文章

LLM系列:1.python入门:15.JSON 数据处理与操作
JSON 数据处理与操作一. 认识JSON与Python类型的映射关系JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。在 Python 中我们不需要安装第三方库直接导入内置的json模块即可importjson核心概念JSON 本质上只是一串“带有特定格式的文本字符串”。在代码中操作时我们需要将其与 Python 内存中的数据结构字典、列表相互转换。JSON 数据类型对应的 Python 数据类型object({})dict(字典)array([])list(列表)string( )str(字符串JSON 强制要求双引号)numberint或float(整型或浮点型)true/falseTrue/False(布尔值Python首字母大写)nullNone(空值)二. 前置知识Python 原生文件操作 (open with…as)在将数据写入磁盘或从磁盘读取之前我们必须先通过操作系统“打开”目标文件建立数据传输管道。在 Python 中这通常由内置的open()函数配合with ... as语法来完成。1. open - 打开文件对象作用在内存和本地磁盘文件之间建立一条连接返回一个可操作的文件对象。注使用纯open()打开文件后程序使用完毕时必须显式调用.close()关闭文件否则会占用系统资源甚至导致文件损坏open(file,moder,encodingNone)参数文件路径 (file) 需要打开的目标文件路径str 或 Path 对象。操作模式 (mode) 指定打开文件的目的str。深度学习中最常用的有r 只读模式默认。文件必须存在用于读取数据。w 覆盖写入模式。文件不存在则创建文件若存在则完全清空原内容再写a 追加写入模式。文件不存在则创建存在则在文件最末尾继续追加内容。字符编码 (encoding) 指定文本的编解码方式。处理含中文或特殊符号的数据集时强烈推荐固定设为utf-8str。返回值成功 返回一个可供读写操作的文件指针对象通常为 TextIOWrapper。示例# 传统写法极不推荐极其容易忘记 close 导致文件被占用fopen(test.txt,w,encodingutf-8)f.write(Hello World!)f.close()# 必须手动执行这一句2. with … as - 优雅的上下文管理器作用with语句用于包装带有生命周期管理的对象如文件读写、数据库连接。它的核心魅力在于无论缩进的代码块内部是否发生报错崩溃只要代码脱离了with的缩进层级Python 都会百分之百自动帮你执行.close()关闭并保存文件withopen(file,mode,encoding)asf:# 在这里的缩进块内对文件 f 进行读写操作pass# 缩进结束f 自动关闭参数无特定函数参数这是 Python 的语法关键字。as后面紧跟的是给这个文件对象起的变量名科研代码中习惯简写为f、file或fin/fout。返回值无直接返回值。示例# 现代标准写法极度推荐安全且优雅withopen(test.txt,w,encodingutf-8)asf:f.write(Hello World!)# 不需要写 f.close()缩进结束时系统自动安全关闭文件三. 内存中字符串与对象的相互转换 (dumps loads)带有s(代表 string) 的方法用于在内存中将“Python 对象”和“JSON 格式的字符串”相互转换。1. json.dumps - 将对象序列化为 JSON 字符串作用将 Python 对象如字典、列表转化为 JSON 格式的字符串。常用于打印输出或准备写入文件。json.dumps(obj,ensure_asciiTrue,indentNone)参数对象 (obj) 需要被转换的 Python 对象通常是dict或list。保证ASCII (ensure_ascii)【极其重要】如果数据中包含中文必须设置为False否则中文会被转码为\uXXXX格式的乱码bool默认为 True缩进 (indent) 格式化输出。指定缩进的空格数让打印出来的 JSON 具有美观的层级结构int 或 None。返回值成功 返回一个符合 JSON 规范的字符串str。示例data{instruction:你好,output:世界}# 默认转换 (中文会变乱码且没有换行)res1json.dumps(data)# {instruction: \\u4f60\\u597d, output: \\u4e16\\u754c}# 深度学习常用标准参数不转译中文且缩进 4 格对齐res2json.dumps(data,ensure_asciiFalse,indent4)# {# instruction: 你好,# output: 世界# }print(type(res2))# class str2. json.loads - 将 JSON 字符串反序列化为对象作用将符合 JSON 语法的文本字符串解析为 Python 内存中的真实对象如字典。json.loads(s)参数字符串 (s) 包含合法 JSON 数据的文本字符串str。返回值成功 返回解析后的 Python 对象通常是 dict 或 list。示例json_str{model: llama-3, parameters: 70}# 解析回 Python 字典parsed_datajson.loads(json_str)print(parsed_data[model])# 输出: llama-3print(type(parsed_data))# class dict四. 磁盘上文件的读取与写入 (dump load)不带s的方法必须配合上文提到的open()文件指针使用直接将对象塞入文件省去了手动读写字符串的步骤。1. json.dump - 将对象直接写入 JSON 文件作用将 Python 对象直接序列化并写入到本地.json文件中。json.dump(obj,fp,ensure_asciiTrue,indentNone)参数对象 (obj) 需要保存的 Python 数据对象Any。文件指针 (fp) 通过with open(..., w)打开的文件对象TextIOWrapper。保证ASCII (ensure_ascii) / 缩进 (indent) 用法与dumps完全一致。返回值成功 无返回值NoneType数据被安全保存在本地。示例config{learning_rate:2e-5,batch_size:32,model_name:Qwen-7B}# 使用 with open 语法安全地打开文件写入withopen(training_config.json,w,encodingutf-8)asf:json.dump(config,f,ensure_asciiFalse,indent4)2. json.load - 直接从 JSON 文件读取对象作用读取本地.json文件的内容并直接解析为 Python 对象。json.load(fp)参数文件指针 (fp) 通过with open(..., r)打开的文件对象TextIOWrapper。返回值成功 返回解析后的 Python 对象通常是 dict 或 list。示例# 读取刚才保存的配置文件withopen(training_config.json,r,encodingutf-8)asf:loaded_configjson.load(f)print(loaded_config[learning_rate])# 2e-05五. 深度学习科研特供JSONL 文件处理在大模型训练如 SFT 微调时极少使用标准的单个大.json文件。因为当数据集包含百万条对话时整体读取一个 JSON 文件会撑爆内存。行业标准是使用.jsonlJSON Lines格式每一行都是一个独立的、合法的 JSON 字典对象。1. 读取 JSONL 数据集思路利用标准的open()逐行遍历文件然后对取出的每一行字符串使用json.loads()进行解析。dataset[]# 逐行读取 JSONL 文件withopen(sft_data.jsonl,r,encodingutf-8)asf:forlineinf:# 去除行末换行符并解析该行为字典recordjson.loads(line.strip())dataset.append(record)print(f总共加载了{len(dataset)}条训练数据)2. 写入 JSONL 数据集思路遍历 Python 列表中的每一个字典用json.dumps()转化为单行字符串后写入并手动加上换行符\n。results[{prompt:11?,response:2},{prompt:Python的作者是谁,response:Guido van Rossum}]# 追加写入 JSONL 文件 (这里演示用 a 模式追加)withopen(output_results.jsonl,a,encodingutf-8)asf:foriteminresults:# 注意写入 JSONL 时indent 必须保持默认的 None确保每个对象严格挤在一行json_stringjson.dumps(item,ensure_asciiFalse)f.write(json_string\n)六. 高频踩坑避雷指南 (TypeError 报错)在科研中你会经常把模型的输出Tensor或 NumPy 数组保存到 JSON 里此时极易遇到以下报错TypeError: Object of type ndarray / Tensor / float32 is not JSON serializable原因json库非常基础它只认识 Python 原生的dict,list,int,float,str等。它完全不认识NumPy 数组或 PyTorch 的张量终极解决方案在传给json之前强制降维降级为 Python 原生类型。importnumpyasnpimporttorch vector_npnp.array([1.1,2.2,3.3])tensor_pttorch.tensor([4.4,5.5])# 错误示范# json.dumps({data: vector_np}) # 报错# 正确处理# 1. 标量类型使用 .item() 转化为原生 float/int# 2. 数组/张量使用 .tolist() 转化为原生嵌套 listsafe_data{np_vector:vector_np.tolist(),pt_tensor:tensor_pt.tolist(),loss_value:tensor_pt[0].item()}# 此时可以完美保存json.dumps(safe_data)

更多文章