NumPy数组不是JSON可序列化的
创buildNumPy数组并将其保存为Django上下文variables后,加载网页时收到以下错误消息:
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
这是什么意思?
我经常“对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)
你可以使用pandas :
import pandas as pd pd.Series(your_array).to_json(orient='values')
我有一个与它的一些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
这在默认情况下不受支持,但您可以使其工作非常轻松! 如果您想要返回完全相同的数据,则需要编码几件事:
- 数据本身,你可以得到与
obj.tolist()
作为@travelingbones提到。 有时候这可能是够好的。 - 数据types。 我觉得在某些情况下这很重要。
- 如果你假设input的话,可以从上面得到的维数(不一定是2D)确实总是一个“矩形”的网格。
- 内存顺序(行或列)。 这往往不重要,但有时它(例如表演),所以为什么不保存一切?
此外,你的numpy数组可能是你的数据结构的一部分,例如你有一个列表里面有一些matrix。 为此,您可以使用基本上是上述的自定义编码器。
这应该足以实现一个解决scheme。 或者你可以使用json-tricks这样做(并支持其他types)(免责声明:我做到了)。
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))
此外,一些非常有趣的信息进一步列表与数组在Python〜> Python列表与数组 – 何时使用?
可以注意到,一旦我把我的数组转换成一个列表之前,将其保存在一个JSON文件中,在我的部署中,无论如何,一旦我读了这个JSON文件供以后使用,我可以继续使用它的列表forms反对把它转换回数组)。
AND在屏幕上看起来更好(在我看来),就像列表(逗号分隔)和数组(不逗号分隔)一样。
使用上面的@toursbones的.tolist()方法,我一直在使用(捕捉到我发现的一些错误):
保存字典
def writeDict(values, name): writeName = DIR+name+'.json' with open(writeName, "w") as outfile: json.dump(values, outfile)
阅读DICTIONARY
def readDict(name): readName = DIR+name+'.json' try: with open(readName, "r") as infile: dictValues = json.load(infile) return(dictValues) except IOError as e: print(e) return('None') except ValueError as e: print(e) return('None')
希望这可以帮助!
这里是一个实现,为我工作,并删除所有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