在创建NumPy数组后,并将其保存为Django上下文变量,我在加载网页时收到以下错误:
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
这是什么意思?
在创建NumPy数组后,并将其保存为Django上下文变量,我在加载网页时收到以下错误:
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
这是什么意思?
当前回答
如果你在字典中嵌套了numpy数组,我发现了最好的解决方案:
import json
import numpy as np
class NumpyEncoder(json.JSONEncoder):
""" Special json encoder for numpy types """
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
dumped = json.dumps(data, cls=NumpyEncoder)
with open(path, 'w') as f:
json.dump(dumped, f)
多亏了这个家伙。
其他回答
我经常“jsonify”np.arrays。首先尝试在数组上使用".tolist()"方法,如下所示:
import numpy as np
import codecs, json
a = np.arange(10).reshape(2,5) # a 2 by 5 array
b = a.tolist() # nested lists with same data, indices
file_path = "/path.json" ## your path variable
json.dump(b, codecs.open(file_path, 'w', encoding='utf-8'),
separators=(',', ':'),
sort_keys=True,
indent=4) ### this saves the array in .json format
为了“unjsonify”数组使用:
obj_text = codecs.open(file_path, 'r', encoding='utf-8').read()
b_new = json.loads(obj_text)
a_new = np.array(b_new)
使用json。转储默认kwarg:
Default应该是一个函数,用于无法序列化的对象. ...或引发TypeError
在默认函数中检查对象是否来自模块numpy,如果是,则使用ndarray。对ndarray使用列表,对任何其他numpy特定类型使用.item。
import numpy as np
def default(obj):
if type(obj).__module__ == np.__name__:
if isinstance(obj, np.ndarray):
return obj.tolist()
else:
return obj.item()
raise TypeError('Unknown type:', type(obj))
dumped = json.dumps(data, default=default)
默认情况下不支持这一点,但是您可以很容易地让它工作!如果你想要返回完全相同的数据,有几个东西你需要编码:
数据本身,您可以通过obj.tolist()获得,如@travelingbones所述。有时这可能已经足够好了。 数据类型。我觉得这在很多情况下很重要。 维度(不一定是2D),如果你假设输入确实总是一个“矩形”网格,可以从上面得到。 内存顺序(行或列为主)。这通常并不重要,但有时很重要(例如性能),所以为什么不保存所有内容呢?
此外,你的numpy数组可以是你的数据结构的一部分,例如,你有一个包含一些矩阵的列表。为此,你可以使用一个自定义编码器,基本上做上述。
这应该足以实现解决方案。或者你可以使用json-tricks,它可以做到这一点(并支持各种其他类型)(免责声明:是我做的)。
pip install json-tricks
Then
data = [
arange(0, 10, 1, dtype=int).reshape((2, 5)),
datetime(year=2017, month=1, day=19, hour=23, minute=00, second=00),
1 + 2j,
Decimal(42),
Fraction(1, 3),
MyTestCls(s='ub', dct={'7': 7}), # see later
set(range(7)),
]
# Encode with metadata to preserve types when decoding
print(dumps(data))
存储为JSON一个numpy。Ndarray或任何嵌套列表组合。
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
json_dump = json.dumps({'a': a, 'aa': [2, (2, 3, 4), a], 'bb': [2]},
cls=NumpyEncoder)
print(json_dump)
将输出:
(2, 3)
{"a": [[1, 2, 3], [4, 5, 6]], "aa": [2, [2, 3, 4], [[1, 2, 3], [4, 5, 6]]], "bb": [2]}
从JSON中恢复:
json_load = json.loads(json_dump)
a_restored = np.asarray(json_load["a"])
print(a_restored)
print(a_restored.shape)
将输出:
[[1 2 3]
[4 5 6]]
(2, 3)
这是一个不同的答案,但这可能有助于那些试图保存数据然后再次读取的人。 有一种方法比泡菜更快更容易。 我试图保存并在pickle dump中阅读它,但在阅读时有很多问题,浪费了一个小时,尽管我正在用自己的数据创建一个聊天机器人,但仍然没有找到解决方案。
Vec_x和vec_y是numpy数组:
data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )
然后你只需读取它并执行以下操作:
data2 = hkl.load( 'new_data_file.hkl' )