«TypeError: (Integer) не является сериализуемым JSON» при сериализации JSON в Python?

163

Я пытаюсь отправить простой словарь в файл json из python, но получаю сообщение «TypeError: 1425 is JSON serializable».

import json
alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 15:30']}
afile = open('test.json','w')
afile.write(json.dumps(alerts,encoding='UTF-8'))
afile.close()

Если я добавлю аргумент по умолчанию, то он записывает, но целочисленные значения записываются в файл json в виде строк, что нежелательно.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
user1329894
источник
1
Это не похоже на «дублирование» этого вопроса ..
8
Я нашел свою проблему. Проблема заключалась в том, что мои целые числа были на самом деле типа numpy.int64.
user1329894
@ user1329894 Опубликовать как решение / объяснение и самозакрытие ..
-0 для написания минимального репро, который фактически не воспроизводит ошибку.
Рассел Борогове

Ответы:

268

Я нашел свою проблему. Проблема заключалась в том, что мои целые числа были типом numpy.int64.

user1329894
источник
22
Мне тоже пришлось столкнуться с этой проблемой, и ваш ответ указал мне правильное направление. Я просто хотел добавить ссылку на другой вопрос, который может помочь в решении проблемы.
JAC
19
Было бы неплохо, если бы сообщение об ошибке JSON могло не отображать тип объекта ...
Франк Дернонкур
6
Вот аккуратное решение, которое использует собственный сериализатор.
Оуэн
17
Это проблема, но в чем решение?
BallpointBen
5
x.astype (int) или int (x)
zelcon
50

Кажется, что может быть проблема с выгрузкой numpy.int64 в строку json в Python 3, и команда разработчиков python уже обсуждает это. Более подробную информацию можно найти здесь .

Обходной путь предоставил Сергей Сторчака. Это работает очень хорошо, поэтому я вставляю это здесь:

def convert(o):
    if isinstance(o, numpy.int64): return int(o)  
    raise TypeError

json.dumps({'value': numpy.int64(42)}, default=convert)
HSC
источник
Прекрасный обходной путь, предоставленный Сергеем. Пожалуйста, проверьте его подход. А для добавления просто: json.dumps (yourObject, default = default); как здесь.
Пранцелль,
4

Это решило проблему для меня:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }
Тобиас Эрнст
источник
4

Просто конвертируйте числа из int64(из numpy) в int.

Например, если переменная xявляется int64:

int(x)

Если это массив int64:

map(int, x)
Джонатас Эдуардо
источник
3

Как отметил @JAC в комментариях ответа с наивысшим рейтингом, общее решение (для всех типов numpy) можно найти в потоке Преобразование ntypty dtypes в нативные типы python .

Тем не менее, я добавлю свою версию решения ниже, так как в моем случае мне нужно общее решение, которое объединяет эти ответы и с ответами из другой ветки. Это должно работать почти со всеми типами NumPy.

def convert(o):
    if isinstance(o, np.generic): return o.item()  
    raise TypeError

json.dumps({'value': numpy.int64(42)}, default=convert)
детская коляска
источник
Хороший ответ действительно
jtlz2
2

Это может быть поздний ответ, но недавно я получил ту же ошибку. После большого количества серфинга это решение помогло мне.

alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 15:30']}
def myconverter(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()
        elif isinstance(obj, datetime.datetime):
            return obj.__str__()

Звоните myconverterв , json.dumps()как показано ниже.json.dumps(alerts, default=myconverter).

шива
источник
1

В качестве альтернативы вы можете сначала преобразовать ваш объект в массив данных:

df = pd.DataFrame(obj)

и затем сохраните это dataframeв jsonфайл:

df.to_json(path_or_buf='df.json')

Надеюсь это поможет

Картик
источник
0

У вас есть Numpy Data Type, просто измените на обычный тип данных int () или float (). это будет работать нормально.

Шрирам Арвинд Лакшманакумар
источник
0

Та же проблема. Список содержит номера типа numpy.int64, который выдает ошибку TypeError. Быстрый обходной путь для меня был

mylist = eval(str(mylist_of_integers))
json.dumps({'mylist': mylist})

которая преобразует список в str (), а функция eval () вычисляет «String» как выражение Python и возвращает результат в виде списка целых чисел в моем случае.

user319436
источник
Просто заметил, что eval (str ()) очень медленный, поэтому используйте его с осторожностью. Ответ @ Шивы намного лучше: json.dumps (оповещения, по умолчанию = myconverter)
user319436
0

использование

from numpyencoder import NumpyEncoder

чтобы решить эту проблему в Python3:

import json
from numpyencoder import NumpyEncoder
alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 
15:30']}
afile = open('test.json','w')
afile.write(json.dumps(alerts,encoding='UTF-8',cls=NumpyEncoder))
afile.close()
Кришна Кумар Мишра
источник