我正在尝试编写一个 JSONEncoder,以便可以将一些 Python 对象数据转储为 JSON 文本,以便由另一个应用程序读取。我在转换 numpy 数组时遇到特别麻烦。我读过很多关于这个主题的文章,并且在这篇文章 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)
当我创建一个简单的运动对象,然后调用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 ndarray 类型的返回值以返回列表而不是字典来解决这个问题。我使用了 numpy 内置方法 tolist()
,它返回 ndarray 的 json 编码表示。
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)
## converting to base64 and returning a dictionary did not work
## return dict(__ndarray__ = data_b64, dtype = str(obj.dtype), shape = obj.shape)
return obj.tolist() ## instead, utilize numpy builtin tolist() method
try:
my_dict = obj.__dict__ ## <-- ERROR raised here
except TypeError:
pass
else:
return my_dict
return json.JSONEncoder.default(self, obj)
关于python - 无法将 numpy 数组转换为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36435039/