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

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

这是什么意思?


当前回答

我有一个类似的问题,嵌套字典与一些numpy。ndarray在里面。

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

其他回答

你可以使用Pandas:

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

如果你在字典中嵌套了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)

多亏了这个家伙。

下面是一个为我工作的实现,并删除了所有的nan(假设这些是简单的对象(list或dict)):

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

默认情况下不支持这一点,但是您可以很容易地让它工作!如果你想要返回完全相同的数据,有几个东西你需要编码:

数据本身,您可以通过obj.tolist()获得,如@travelingbones所述。有时这可能已经足够好了。 数据类型。我觉得这在很多情况下很重要。 维度(不一定是2D),如果你假设输入确实总是一个“矩形”网格,可以从上面得到。 内存顺序(行或列为主)。这通常并不重要,但有时很重要(例如性能),所以为什么不保存所有内容呢?

此外,你的numpy数组可以是你的数据结构的一部分,例如,你有一个包含一些矩阵的列表。为此,你可以使用一个自定义编码器,基本上做上述。

这应该足以实现解决方案。或者你可以使用json-tricks,它可以做到这一点(并支持各种其他类型)(免责声明:是我做的)。

pip install json-tricks

Then

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

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