NumPy数组无法序列化为JSON

453 投票
16 回答
528663 浏览
提问于 2025-04-30 13:32

在创建了一个NumPy数组,并把它保存为Django的上下文变量后,当我加载网页时,出现了以下错误:

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

这是什么意思呢?

暂无标签

16 个回答

51

使用 json.dumpsdefault 参数:

default 应该是一个函数,当遇到无法直接转换成 JSON 格式的对象时会被调用。... 或者引发一个类型错误(TypeError)。

在这个 default 函数里,检查一下这个对象是不是来自 numpy 模块。如果是的话,对于 ndarray 类型的对象,可以使用 ndarray.tolist 方法;对于其他 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)
73

你可以使用Pandas这个库:

import pandas as pd
pd.Series(your_array).to_json(orient='values')
102

我找到了一个很好的解决办法,适用于字典中有嵌套的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)

感谢这位朋友

442

将一个numpy.ndarray或者任何嵌套列表的组合存储为JSON格式。

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

我经常需要把 np.arrays 转换成 JSON 格式。你可以先试试对数组使用 ".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

要把数组转换回原来的格式,可以使用:

obj_text = codecs.open(file_path, 'r', encoding='utf-8').read()
b_new = json.loads(obj_text)
a_new = np.array(b_new)

撰写回答