直接用 json.dumps() 会报错,因为 ndarray 不是 JSON 可序列化类型;最通用解法是 arr.tolist() 转为嵌套 list,但会丢失 dtype、nan/inf 需预处理。
为什么直接用
js
on.dumps() 会报错:Object of type ndarray is not JSON serializable
NumPy 数组(
)不是 Python 原生类型,
默认只认
、
、
、
、
、
和
。遇到
就直接抛出这个错误,不给商量余地。
根本原因在于 JSON 标准里没有“多维数组”原语,而 NumPy 的内存布局、dtype、形状信息等都无法被 JSON 编码器自动理解。
最轻量、最通用的解法就是调用
——它把
递归转成嵌套的 Python
,完全符合 JSON 可序列化要求:
tolist() 的行为细节:dtype 会丢失,但值和结构保留
只保证数值和嵌套结构正确,不保留原始
、内存顺序(C/F order)、或是否为视图(view)等 NumPy 特有属性。反序列化回来时,默认是
或
,取决于 JSON 解析器推断。
立即学习
“
Python免费学习笔记(深入)
”;
整数数组转成
后,再
得到的是 Python
,不是
浮点数组中若含
或
,
会转成
、
等,而标准 JSON 不支持
,
会报错 —— 需提前处理
高维数组(如 4D)也能转,但生成的嵌套
层级深,可读性差,传输体积也比二进制大得多
遇到 nan/inf 怎么办:先替换再 tolist
JSON 规范明确不支持
、
,所以含这些值的数组调
后,
仍会崩,报错信息是:
。
Find JSON Path Online
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
下载
稳妥做法是在调用
前,用
或手动掩码替换:
注意:
是合法 JSON 值,但反序列化后是 Python
,不是
;如需还原,必须额外记录缺失位置。
要不要考虑更快或更省空间的方案?
如果只是偶尔传小数组,
完全够用;但以下场景建议换方式:
高频传输大数组(>1MB):JSON 文本体积比二进制大 2–5 倍,解析也慢。改用
/
(本地)或
+
(网络)
需要保留 dtype 和 shape:JSON 本身做不到,得额外字段存
和
,再手写反构逻辑 —— 复杂度陡增,不如直接用
或
(注意安全限制)
前端 JS 需要消费:
输出的嵌套数组 JS 可直接
,是最兼容的选择;别尝试让 JS 直接解析 NumPy 二进制格式
真正容易被忽略的是:
对超大数组可能触发内存峰值(先建 Python list 再转 JSON),如果内存敏感,应分块处理或改用流式序列化方案。
ndarrayjson.dumps()dictliststrintfloatboolNonendarraytolist()ndarraylistimport numpy as np
import json
arr = np.array([[1, 2], [3, 4]], dtype=np.int32)
json_str = json.dumps(arr.tolist()) # ✅ 成功
tolist()dtypefloat64int64listjson.loads()intnp.int32np.nannp.inftolist()Nonefloat('nan')NaNjson.dumps()listNaNInfinitytolist()json.dumps()Out of range float values are not JSON complianttolist()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())
NoneNonenp.nantolist() + jsonnp.save()np.load()msgpacknumpy.ndarray.tobytes()arr.dtype.strarr.shapejoblibpickletolist()JSON.parse()tolist()