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


1
Это не похоже на «дублирование» этого вопроса ..

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

@ user1329894 Опубликовать как решение / объяснение и самозакрытие ..

-0 для написания минимального репро, который фактически не воспроизводит ошибку.
Рассел Борогове

Ответы:


268

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


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)

Прекрасный обходной путь, предоставленный Сергеем. Пожалуйста, проверьте его подход. А для добавления просто: json.dumps (yourObject, default = default); как здесь.
Пранцелль,


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.int64, который выдает ошибку TypeError. Быстрый обходной путь для меня был

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

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


Просто заметил, что 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()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.