无法将numpy数组转换为JSON。

12 浏览
0 Comments

无法将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

编辑:更新了代码以显示错误发生的位置

0
0 Comments

在上述代码中,问题出现在将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字符串。

0