python json.dumps raise TypeError(repr(o) + " is not JSON serializable") TypeError: 0 is not JSON ...

本文介绍了如何解决Python中使用json.dumps遇到的问题,当字典中包含numpy.int64或numpy.float等类型时会导致出错。文章提供了将这些类型转换为Python内置类型的方法,从而避免错误发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  出错如题。

  这个问题有可能是因为python的json.dumps没法识别dump内容里的某些数据类型导致的。我的问题是因为dict中含有numpy.int64,numpy.float等类型导致的,需要先把这些numpy的数据类型转化为相应的python数据类型,如int,float,之后就可以正常运行了。

转载于:https://www.cnblogs.com/zichun-zeng/p/10309486.html

<think>我们被要求解决一个特定的错误:当使用`json.dumps`时,遇到`Object of type ndarray is not JSON serializable`。根据引用[2]和[3],我们可以知道这个错误是因为`json.dumps`默认无法处理numpy的ndarray类型。我们需要提供一个自定义的序列化方法。 解决方案有两种常见方式: 1. 使用`default`参数:提供一个函数,该函数在遇到无法序列化的对象时会被调用,返回一个可序列化的对象(如基本类型、列表、字典等)。 2. 创建一个自定义的JSON编码器(继承`json.JSONEncoder`),并覆盖`default`方法,然后在`json.dumps`时使用`cls`参数指定这个编码器。 由于错误信息明确指出了是ndarray类型,我们可以针对ndarray进行转换,将其转换为列表(因为列表是可以被JSON序列化的)。 参考引用[2]中的例子,他们使用了自定义编码器(MyEncoder)来解决ndarray的序列化问题。引用[3]则展示了如何通过一个函数或者利用对象的`__dict__`属性来序列化自定义对象。 对于ndarray,我们可以这样处理: 方法一:使用一个函数作为`default`参数 ```python import json import numpy as np def numpy_serializer(obj): if isinstance(obj, np.ndarray): return obj.tolist() # 将ndarray转换为列表 # 如果需要处理其他numpy类型,可以继续添加 if isinstance(obj, (np.integer, np.floating)): return int(obj) if isinstance(obj, np.integer) else float(obj) # 如果遇到其他无法序列化的类型,抛出TypeError raise TypeError(f"Type {type(obj)} not serializable") # 使用 data = {'array': np.array([1,2,3])} json_str = json.dumps(data, default=numpy_serializer) ``` 方法二:使用自定义编码器类(继承json.JSONEncoder) ```python import json import numpy as np class NumpyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.ndarray): return obj.tolist() if isinstance(obj, (np.integer, np.floating)): return int(obj) if isinstance(obj, np.integer) else float(obj) # 对于其他类型,使用父类的默认方法 return super().default(obj) # 使用 data = {'array': np.array([1,2,3])} json_str = json.dumps(data, cls=NumpyEncoder) ``` 以上两种方法都可以。通常,如果我们需要在多个地方使用,或者需要处理多种特殊类型,自定义编码器类会更方便。 另外,引用[3]还提到了一种简化的方式:如果对象有`__dict__`属性,可以使用`default=lambda o: o.__dict__`,但这通常用于自定义类的实例,对于ndarray并不适用(因为ndarray没有`__dict__`属性)。所以,对于ndarray,我们使用上述的转换方法。 注意:如果数据中同时包含其他numpy类型(如np.int32, np.float64等),我们也需要将它们转换为Python内置类型(如int, float),因为JSON不支持这些numpy标量类型。上面的代码已经考虑了这些情况。 因此,用户可以根据自己的情况选择一种方法。如果只有ndarray,那么可以只处理ndarray;如果还有其他numpy类型,最好一并处理。 现在,我们按照要求生成相关问题。</think>### 解决`Object of type ndarray is not JSON serializable`错误 当使用`json.dumps()`序列化包含NumPy数组(ndarray)的数据时,会出现此错误。这是因为JSON标准仅支持基础数据类型(字符串、数字、列表、字典等),而NumPy数组属于特殊对象类型。以下是三种解决方案: --- #### 方法1:使用自定义编码器(推荐) 创建继承`json.JSONEncoder`的子类,专门处理NumPy类型: ```python import json import numpy as np class NumpyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.ndarray): return obj.tolist() # 将数组转为列表 if isinstance(obj, (np.integer, np.floating)): return int(obj) if isinstance(obj, np.integer) else float(obj) return super().default(obj) # 使用示例 data = {'array': np.array([1, 2, 3])} json_str = json.dumps(data, cls=NumpyEncoder) # 成功输出: {"array": [1, 2, 3]} ``` --- #### 方法2:通过`default`参数使用lambda函数 对于简单场景,直接转换数组为列表: ```python import json import numpy as np data = {'matrix': np.array([[1, 2], [3, 4]])} json_str = json.dumps(data, default=lambda x: x.tolist() if isinstance(x, np.ndarray) else x) ``` --- #### 方法3:手动转换数组后再序列化 在数据传入`json.dumps()`前显式转换: ```python import numpy as np import json # 原始数据包含ndarray data = { 'name': 'test', 'values': np.array([10, 20, 30]) } # 手动转换ndarray为列表 data['values'] = data['values'].tolist() json_str = json.dumps(data) # 正常序列化 ``` --- ### 关键原因说明 - **JSON限制**:JSON标准不支持`ndarray`、`np.int32`等NumPy特有类型[^2]。 - **解决方案本质**:将NumPy类型转换为JSON兼容的基础Python类型(列表/浮点数/整数)。 - **编码器原理**:当`json.dumps()`遇到无法处理的类型时,会调用`default`函数或自定义`JSONEncoder`[^3]。 --- ### 相关问题 1. 如何序列化包含多个NumPy数组的嵌套字典? 2. 除了`ndarray`,还有哪些Python对象不能被`json.dumps()`直接序列化? 3. 如何反序列化JSON数据并重新转换为NumPy数组? 4. 自定义JSON编码器如何处理Pandas的`DataFrame`类型?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值