在创建NumPy数组后,并将其保存为Django上下文变量,我在加载网页时收到以下错误:

array([   0,  239,  479,  717,  952, 1192, 1432, 1667], dtype=int64) is not JSON serializable

这是什么意思?


当前回答

如果其他人的代码(例如模块)正在执行json.dumps(),其他答案将不起作用。这种情况经常发生,例如,web服务器自动将其返回响应转换为JSON,这意味着我们不能总是更改JSON .dump()的参数。 这个答案解决了这个问题,并且基于一个(相对)新的解决方案,适用于任何第三方类(不仅仅是numpy)。

TLDR

PIP安装json_fix

import json_fix # import this anytime before the JSON.dumps gets called
import json

# create a converter
import numpy
json.fallback_table[numpy.ndarray] = lambda array: array.tolist()

# no additional arguments needed: 
json.dumps(
   dict(thing=10, nested_data=numpy.array((1,2,3)))
)
#>>> '{"thing": 10, "nested_data": [1, 2, 3]}'

其他回答

可以做简单的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()

存储为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)

此外,还有一些关于Python中的列表与数组的非常有趣的信息~> Python列表与数组-何时使用?

可以注意到,一旦我在将数组保存到JSON文件中之前将其转换为列表,无论如何,在我现在的部署中,一旦我读取该JSON文件以供以后使用,我就可以继续以列表形式使用它(而不是将其转换回数组)。

在我看来,AND在屏幕上作为一个列表(逗号分隔)比数组(非逗号分隔)看起来更好。

使用上面的@travelingbones的.tolist()方法,我一直在使用这样的方法(捕捉一些我发现的错误):

保存字典

def writeDict(values, name):
    writeName = DIR+name+'.json'
    with open(writeName, "w") as outfile:
        json.dump(values, outfile)

读字典

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')

希望这能有所帮助!

你也可以使用default参数,例如:

def myconverter(o):
    if isinstance(o, np.float32):
        return float(o)

json.dump(data, default=myconverter)

我经常“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)