You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套defaultdict含NumPy数组的JSON序列化问题(NumPy 2.0)

解决嵌套defaultdict中NumPy类型的JSON序列化问题

你的核心问题是自定义转换函数未被应用到整个嵌套结构,导致json.dump先遇到无法序列化的NumPy数组直接报错。以下是两种可靠的解决方法:

方法一:提前递归转换整个数据结构

先遍历嵌套的defaultdict、列表等结构,将所有NumPy类型转为Python基础类型,同时把defaultdict转为普通dict(JSON原生支持普通字典)。

完善递归转换函数

import numpy as np
from collections import defaultdict

def make_json_serializable(obj):
    # 把defaultdict转为普通字典
    if isinstance(obj, defaultdict):
        obj = dict(obj)
    # 递归处理列表中的每个元素
    if isinstance(obj, list):
        return [make_json_serializable(item) for item in obj]
    # NumPy数组转为Python列表
    if isinstance(obj, np.ndarray):
        return obj.tolist()
    # NumPy标量类型转为Python原生数值类型
    if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
                        np.int16, np.int32, np.int64, np.uint8,
                        np.uint16, np.uint32, np.uint64)):
        return int(obj)
    if isinstance(obj, (np.float_, np.float16, np.float32, np.float64)):
        return float(obj)
    # 处理np.nan(JSON不原生支持NaN,可转为None或保留float('nan'),按需选择)
    if isinstance(obj, float) and np.isnan(obj):
        return None
    # 原生Python类型直接返回
    return obj

使用方式

import json

# 先转换整个数据结构为可序列化格式
serializable_data = make_json_serializable(data_to_save)

# 写入JSON文件
with open("simulation_results.json", "w") as f:
    json.dump(serializable_data, f, indent=4)

方法二:利用json.dump的default参数动态处理

不需要提前转换整个结构,而是让json.dump在遇到无法序列化的类型时,自动调用你的转换逻辑,同时处理defaultdict和NumPy类型。

实现default回调函数

import json
import numpy as np
from collections import defaultdict

def json_serializer(obj):
    # 处理NumPy数组
    if isinstance(obj, np.ndarray):
        return obj.tolist()
    # 处理NumPy标量
    if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
                        np.int16, np.int32, np.int64, np.uint8,
                        np.uint16, np.uint32, np.uint64)):
        return int(obj)
    if isinstance(obj, (np.float_, np.float16, np.float32, np.float64)):
        return float(obj)
    # 处理np.nan
    if isinstance(obj, float) and np.isnan(obj):
        return None
    # 处理defaultdict
    if isinstance(obj, defaultdict):
        return dict(obj)
    # 未知类型抛出错误
    raise TypeError(f"无法序列化类型: {type(obj).__name__}")

使用方式

with open("simulation_results.json", "w") as f:
    json.dump(data_to_save, f, default=json_serializer, indent=4)

方案选择

  • 方法一适合需要先验证转换后数据结构、或后续还要复用转换后数据的场景;
  • 方法二更节省内存,适合处理大型仿真结果(无需提前复制整个数据结构)。

内容的提问来源于stack exchange,提问作者STATTHINGY TRENTON

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:01:18