无法将numpy数组转换为JSON。
无法将numpy数组转换为JSON。
我正试图编写一个JSONEncoder,以便将一些Python对象数据转储为JSON文本,以供其他应用程序读取。我尤其难以将numpy数组进行转换。我已经阅读了许多关于这个主题的SO文章,并且在这篇文章SimpleJSON and NumPy array中大量借鉴了@tlausch的解决方案,但我没有成功。
我有一个非常简单的类来演示我的问题:
import numpy as np class Movement: def __init__(self, t1,t2,t3,t4): self._t1 = t1 self._t2 = t2 self._t3 = t3 self._t4 = t4 self._a0 = np.array([0,0,0])
这是我的JSONEncoder的代码:
import json import base64 import numpy as np class MovementEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.ndarray): if obj.flags['C_CONTIGUOUS']: obj_data = obj.data else: cont_obj = np.ascontiguousarray(obj) assert(cont_obj.flags['C_CONTIGUOUS']) obj_data = cont_obj.data data_b64 = base64.b64encode(obj_data) return dict(__ndarray__ = data_b64, dtype = str(obj.dtype), shape = obj.shape) try: my_dict = obj.__dict__ ## <-- ERROR raised here except TypeError: pass else: return my_dict return json.JSONEncoder.default(self, obj)
当我创建一个简单的Movement对象,然后调用encoder.encode(obj)时,我会得到以下错误:
>>> obj = Movement(1,2,3,4) >>> encoder = MovementEncoder() >>> encoder.encode(obj) ... 'bytes' object has no attribute '__dict__'
通过向编码器添加一些打印语句,我可以看到它从对象中正确递归,然后到对象的字典,再到具有np.array类型的属性。我认为这个解决方案的重点是ndarray
类型的base64表示在默认情况下是可以被JSON编码的,但似乎并非如此。我错在哪里?
注意:使用Python 3.4和NumPy 1.8.2
编辑:更新了代码以显示错误发生的位置
在上述代码中,问题出现在将numpy数组转换为JSON时。问题的原因是返回值是一个字典,而不是一个列表。为了解决这个问题,可以使用numpy内置的tolist()
方法,它返回一个可以被JSON编码的ndarray的表示形式。
为了解决这个问题,可以按照以下步骤进行操作:
1. 导入所需的库:json、base64和numpy。
2. 创建一个自定义的JSON编码器类MovementEncoder
,继承自json.JSONEncoder
。
3. 在MovementEncoder
类中,重写default
方法,该方法会在对象无法直接序列化时被调用。
4. 在default
方法中,检查对象是否为numpy.ndarray
类型。
5. 如果是numpy.ndarray
类型,首先检查数组是否是C连续的,如果是,则获取数组的数据;如果不是,则将数组转换为C连续的,并获取数据。
6. 使用tolist()
方法将numpy.ndarray
转换为列表,并返回该列表。
7. 如果对象不是numpy.ndarray
类型,尝试获取对象的字典形式,如果成功,则返回该字典。
8. 如果以上步骤都失败,则调用json.JSONEncoder.default
方法来处理对象的序列化。
通过以上步骤,我们成功解决了将numpy数组转换为JSON时的问题。现在,可以使用json.dumps()
方法将numpy数组转换为JSON字符串。