创建NumPy数组并将其保存为Django上下文变量后,加载网页时收到以下错误:
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
这是什么意思?
答案 0 :(得分:201)
我经常" 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)
答案 1 :(得分:120)
将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)
答案 2 :(得分:32)
您可以使用Pandas:
import pandas as pd
pd.Series(your_array).to_json(orient='values')
答案 3 :(得分:23)
如果您在字典中嵌套了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)
感谢this guy。
答案 4 :(得分:8)
许多其他的numpy编码器似乎过于冗长。
检查对象是否来自numpy模块,如果是,则对ndarray
使用ndarray.tolist
或对其他任何numpy特定类型使用.item
。
使用json.dumps
default
kwarg:
默认值应该是一个针对无法序列化的对象调用的函数。
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)
答案 5 :(得分:4)
默认情况下不支持此功能,但您可以轻松使用它!如果您想要完全相同的数据,有几件事情需要编码:
obj.tolist()
作为@travelingbones提到。有时这可能已经足够了。此外,您的numpy数组可能是您数据结构的一部分,例如你有一个里面有一些矩阵的列表。为此,您可以使用基本上完成上述操作的自定义编码器。
这应该足以实现解决方案。或者你可以使用json-tricks这样做(并支持其他各种类型)(免责声明:我做到了)。
pip install json-tricks
然后
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))
答案 6 :(得分:3)
我在嵌套字典中遇到了类似的问题,其中包含一些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
答案 7 :(得分:3)
您还可以使用default
参数,例如:
def myconverter(o):
if isinstance(o, np.float32):
return float(o)
json.dump(data, default=myconverter)
答案 8 :(得分:2)
使用NumpyEncoder可以成功处理json转储。不抛出-NumPy数组不可JSON序列化
import numpy as np
import json
from numpyencoder import NumpyEncoder
arr = array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64)
json.dumps(arr,cls=NumpyEncoder)
答案 9 :(得分:1)
此外,关于列表与Python中的数组的一些非常有趣的信息〜> Python List vs. Array - when to use?
可以注意到,一旦我将数组转换为列表,然后将其保存在JSON文件中,在我的部署中,无论如何,一旦我读了JSON文件供以后使用,我可以继续在列表中使用它形式(而不是将其转换回数组)。
实际上在屏幕上看起来更好(在我看来)作为列表(逗号分隔)与数组(非逗号分隔)这种方式。
使用上面的@transbones的.tolist()方法,我一直在使用(捕捉到我发现的一些错误):
保存字典
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
drawThumb(c); //redrawing thumb
super.onDraw(c);
}
void drawThumb(Canvas canvas) {
Drawable thumb = getThumb();
if (thumb != null) {
Rect thumbBounds = thumb.getBounds();
canvas.save();
canvas.rotate(90, thumbBounds.exactCenterX(), thumbBounds.exactCenterY());
thumb.draw(canvas);
canvas.restore();
}
}
阅读字典
def writeDict(values, name):
writeName = DIR+name+'.json'
with open(writeName, "w") as outfile:
json.dump(values, outfile)
希望这有帮助!
答案 10 :(得分:1)
这是一个适合我并且删除了所有nans的实现(假设这些是简单的对象(列表或字典)):
from numpy import isnan
def remove_nans(my_obj, val=None):
if isinstance(my_obj, list):
for i, item in enumerate(my_obj):
if isinstance(item, list) or isinstance(item, dict):
my_obj[i] = remove_nans(my_obj[i], val=val)
else:
try:
if isnan(item):
my_obj[i] = val
except Exception:
pass
elif isinstance(my_obj, dict):
for key, item in my_obj.iteritems():
if isinstance(item, list) or isinstance(item, dict):
my_obj[key] = remove_nans(my_obj[key], val=val)
else:
try:
if isnan(item):
my_obj[key] = val
except Exception:
pass
return my_obj
答案 11 :(得分:1)
这是一个不同的答案,但这可能有助于帮助试图保存数据然后再次读取的人。
比起泡菜更快更容易。
我试图保存它并在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' )
答案 12 :(得分:1)
可以使用检查类型简化for循环:
with open("jsondontdoit.json", 'w') as fp:
for key in bests.keys():
if type(bests[key]) == np.ndarray:
bests[key] = bests[key].tolist()
continue
for idx in bests[key]:
if type(bests[key][idx]) == np.ndarray:
bests[key][idx] = bests[key][idx].tolist()
json.dump(bests, fp)
fp.close()
答案 13 :(得分:1)
TypeError:array([[[0.46872085,0.67374235,1.0218339,0.13210179,0.5440686,0.9140083,0.58720225,0.2199381]],dtype = float32)不是JSON可序列化的
当我期望以json格式响应时,尝试将数据列表传递给model.predict()时,抛出了上述错误。
a = []
b = []
while len(a) < 11:
a.append(int(input("enter a number:")))
if len(a) == 10:
break
print('Original keyed in numbers are:',a)
for index in range(len(a)):
if a[index] > 5:
continue
b.append(a[index])
print('These are numbers you entered that are less than or equal to 5:',b)
但幸运的是找到了解决抛出错误的提示 对象的序列化仅适用于以下转换 映射应采用以下方式 对象-dict 数组列表 字符串-字符串 整数-整数
如果向上滚动以查看行号10 预测= loading_model.predict(d)此行代码在其中生成输出的位置 类型为数组数据类型,当您尝试将数组转换为json格式时
最后我找到了解决方案,方法是将获得的输出转换为类型列表 以下代码行
预测= loading_model.predict(d)
列表类型= projection.tolist() 返回jsonify(listtype)