跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Python如何实现NumPy数组与JSON的高效互转_通过tolist方法解决不可序列化问题

直接用 json.dumps() 会报错,因为 ndarray 不是 JSON 可序列化类型;最通用解法是 arr.tolist() 转为嵌套 list,但会丢失 dtype、nan/inf 需预处理。 为什么直接用 js on.dumps() 会报错:Object of type ndarray is not JSON serializable NumPy 数组(
ndarray
)不是 Python 原生类型,
json.dumps()
默认只认
dict
、
list
、
str
、
int
、
float
、
bool
和
None
。遇到
ndarray
就直接抛出这个错误,不给商量余地。 根本原因在于 JSON 标准里没有“多维数组”原语,而 NumPy 的内存布局、dtype、形状信息等都无法被 JSON 编码器自动理解。 最轻量、最通用的解法就是调用
tolist()
——它把
ndarray
递归转成嵌套的 Python
list
,完全符合 JSON 可序列化要求:
import numpy as np import json

arr = np.array([[1, 2], [3, 4]], dtype=np.int32) json_str = json.dumps(arr.tolist()) # ✅ 成功

tolist() 的行为细节:dtype 会丢失,但值和结构保留
tolist()
只保证数值和嵌套结构正确,不保留原始
dtype
、内存顺序(C/F order)、或是否为视图(view)等 NumPy 特有属性。反序列化回来时,默认是
float64
或
int64
,取决于 JSON 解析器推断。 立即学习 “ Python免费学习笔记(深入) ”; 整数数组转成
list
后,再
json.loads()
得到的是 Python
int
,不是
np.int32
浮点数组中若含
np.nan
或
np.inf
,
tolist()
会转成
None
、
float('nan')
等,而标准 JSON 不支持
NaN
,
json.dumps()
会报错 —— 需提前处理 高维数组(如 4D)也能转,但生成的嵌套
list
层级深,可读性差,传输体积也比二进制大得多 遇到 nan/inf 怎么办:先替换再 tolist JSON 规范明确不支持
NaN
、
Infinity
,所以含这些值的数组调
tolist()
后,
json.dumps()
仍会崩,报错信息是:
Out of range float values are not JSON compliant
。 Find JSON Path Online Easily find JSON paths within JSON objects using our intuitive Json Path Finder 下载 稳妥做法是在调用
tolist()
前,用
np.nan_to_num()
或手动掩码替换:
arr = np.array([1.0, np.nan, np.inf, -np.inf]) # 方案一:转为指定填充值(默认 0.0, inf→1.797e+308, -inf→-1.797e+308) safe_arr = np.nan_to_num(arr, nan=0.0, posinf=None, neginf=None) # 方案二:更可控 —— 先标记再替换 mask = np.isnan(arr) | np.isinf(arr) arr_clean = arr.copy() arr_clean[mask] = 0.0 # 或 None,但注意:None 在 list 中会被 dumps 为 null json.dumps(arr_clean.tolist())
注意:
None
是合法 JSON 值,但反序列化后是 Python
None
,不是
np.nan
;如需还原,必须额外记录缺失位置。 要不要考虑更快或更省空间的方案? 如果只是偶尔传小数组,
tolist() + json
完全够用;但以下场景建议换方式: 高频传输大数组(>1MB):JSON 文本体积比二进制大 2–5 倍,解析也慢。改用
np.save()
/
np.load()
(本地)或
msgpack
+
numpy.ndarray.tobytes()
(网络) 需要保留 dtype 和 shape:JSON 本身做不到,得额外字段存
arr.dtype.str
和
arr.shape
,再手写反构逻辑 —— 复杂度陡增,不如直接用
joblib
或
pickle
(注意安全限制) 前端 JS 需要消费:
tolist()
输出的嵌套数组 JS 可直接
JSON.parse()
,是最兼容的选择;别尝试让 JS 直接解析 NumPy 二进制格式 真正容易被忽略的是:
tolist()
对超大数组可能触发内存峰值(先建 Python list 再转 JSON),如果内存敏感,应分块处理或改用流式序列化方案。

相关文章