Kar*_*rus 196 python django json numpy
创建NumPy数组并将其保存为Django上下文变量后,加载网页时收到以下错误:
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
这是什么意思?
tra*_*nes 237
我经常"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
Run Code Online (Sandbox Code Playgroud)
为了"unjsonify"数组使用:
obj_text = codecs.open(file_path, 'r', encoding='utf-8').read()
b_new = json.loads(obj_text)
a_new = np.array(b_new)
Run Code Online (Sandbox Code Playgroud)
小智 169
存储为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)
Run Code Online (Sandbox Code Playgroud)
将输出:
(2, 3)
{"a": [[1, 2, 3], [4, 5, 6]], "aa": [2, [2, 3, 4], [[1, 2, 3], [4, 5, 6]]], "bb": [2]}
Run Code Online (Sandbox Code Playgroud)
要从JSON还原:
json_load = json.loads(json_dump)
a_restored = np.asarray(json_load["a"])
print(a_restored)
print(a_restored.shape)
Run Code Online (Sandbox Code Playgroud)
将输出:
[[1 2 3]
[4 5 6]]
(2, 3)
Run Code Online (Sandbox Code Playgroud)
Joh*_*nck 35
你可以使用熊猫:
import pandas as pd
pd.Series(your_array).to_json(orient='values')
Run Code Online (Sandbox Code Playgroud)
tsv*_*iko 29
如果在字典中嵌套了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.int_, np.intc, np.intp, np.int8,
np.int16, np.int32, np.int64, np.uint8,
np.uint16, np.uint32, np.uint64)):
return int(obj)
elif isinstance(obj, (np.float_, np.float16, np.float32,
np.float64)):
return float(obj)
elif isinstance(obj,(np.ndarray,)): #### This is the fix
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)
Run Code Online (Sandbox Code Playgroud)
谢谢你这个家伙.
mos*_*evi 13
其他一些numpy编码器似乎过于冗长。
使用json.dumps defaultkwarg:
default应该是一个为无法序列化的对象调用的函数。
在default函数中,检查对象是否来自numpy模块,如果是,则将其ndarray.tolist用于ndarray或将其.item用于任何其他特定于numpy的类型。
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)
Run Code Online (Sandbox Code Playgroud)
我对其中有一些 numpy.ndarrays 的嵌套字典也有类似的问题。
def jsonify(data):
json_data = dict()
for key, value in data.iteritems():
if isinstance(value, list): # for lists
value = [ jsonify(item) if isinstance(item, dict) else item for item in value ]
if isinstance(value, dict): # for nested lists
value = jsonify(value)
if isinstance(key, int): # if key is integer: > to string
key = str(key)
if type(value).__module__=='numpy': # if value is numpy.*: > to python list
value = value.tolist()
json_data[key] = value
return json_data
Run Code Online (Sandbox Code Playgroud)
默认情况下不支持此功能,但是您可以使其轻松工作!如果您想返回完全相同的数据,则需要对几件事进行编码:
obj.tolist()@travelingbones 获得。有时这可能已经足够了。此外,您的numpy数组可能是数据结构的一部分,例如,您有一个包含一些矩阵的列表。为此,您可以使用自定义编码器,基本上可以完成上述操作。
这应该足以实施解决方案。或者,您可以使用json-tricks来做到这一点(并支持其他各种类型)(免责声明:我做到了)。
pip install json-tricks
Run Code Online (Sandbox Code Playgroud)
然后
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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
184530 次 |
| 最近记录: |