"TypeError: (Inteiro) não é JSON serializável" ao serializar JSON em Python?

162

Estou tentando enviar um dicionário simples para um arquivo json a partir de python, mas continuo recebendo a mensagem "TypeError: 1425 is not 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()

Se eu adicionar o argumento padrão, ele gravará, mas os valores inteiros serão gravados no arquivo json como seqüências de caracteres, o que é indesejável.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
user1329894
fonte
1
Este não parece "duplicar" a essa pergunta ..
8
Eu encontrei o meu problema. O problema era que meus números inteiros eram realmente do tipo numpy.int64.
user1329894
@ user1329894 Publique como uma solução / explicação e feche ..
-0 para escrever uma reprodução mínima que não reproduza o bug.
Russell Borogove

Respostas:

268

Eu encontrei o meu problema. O problema era que meus números inteiros eram realmente do tipo numpy.int64.

user1329894
fonte
22
Eu também tive que lidar com esse problema, e sua resposta me apontou na direção certa. Eu só queria adicionar um link para outra pergunta que possa ajudar a realmente resolver o problema.
JAC
19
Isso seria bom se a mensagem de erro unserializable JSON pode exibir o tipo do objeto ...
Franck Dernoncourt
6
Aqui está uma solução organizada que usa um serializador personalizado.
Owen
17
Esse é o problema, mas qual é a solução?
BallpointBen
5
x.astype (int) ou int (x)
zelcon
50

Parece que pode haver um problema para despejar numpy.int64 na string json no Python 3 e a equipe do python já tem uma conversa sobre isso. Mais detalhes podem ser encontrados aqui .

Existe uma solução alternativa fornecida por Serhiy Storchaka. Funciona muito bem, então colo aqui:

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

json.dumps({'value': numpy.int64(42)}, default=convert)
hsc
fonte
Uma solução alternativa maravilhosa fornecida por Serhiy. Por favor, verifique sua abordagem. E para adicionar, apenas: json.dumps (yourObject, default = default); como aqui.
Pranzell 16/04/19
4

Isso resolveu o problema para mim:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }
Tobias Ernst
fonte
4

Basta converter números de int64(de numpy) para int.

Por exemplo, se a variável xfor int64:

int(x)

If é a matriz do int64:

map(int, x)
Jonatas Eduardo
fonte
3

como o @JAC apontou nos comentários da resposta com a classificação mais alta, a solução genérica (para todos os tipos numpy) pode ser encontrada no segmento Convertendo tipos numpy em tipos nativos de python .

No entanto, adicionarei minha versão da solução abaixo, pois, no meu caso, eu precisava de uma solução genérica que combine essas respostas e as do outro segmento. Isso deve funcionar com quase todos os tipos numpy.

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

json.dumps({'value': numpy.int64(42)}, default=convert)
Buggy
fonte
Resposta agradável mesmo
jtlz2 26/03
2

Esta pode ser a resposta tardia, mas recentemente recebi o mesmo erro. Depois de muita navegação, essa solução me ajudou.

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

Chamada myconverterem json.dumps()como abaixo.json.dumps(alerts, default=myconverter).

shiva
fonte
1

Como alternativa, você pode converter seu objeto em um dataframe primeiro:

df = pd.DataFrame(obj)

e salve isso dataframeem um jsonarquivo:

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

Espero que isto ajude

kartik
fonte
0

Você possui o tipo de dados Numpy, basta alterar para o tipo de dados normal int () ou float (). funcionará bem.

Sriram Arvind Lakshmanakumar
fonte
0

Mesmo problema. Lista de números contidos do tipo numpy.int64 que gera um TypeError. Solução rápida para mim foi

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

que converte list em str () e eval () avalia a "String" como uma expressão python e retorna o resultado como uma lista de números inteiros no meu caso.

user319436
fonte
Acabei de notar que eval (str ()) é muito lento, portanto, use com cuidado. A resposta do @ shiva é muito melhor: json.dumps (alertas, padrão = myconverter)
user319436 24/04
0

usar

from numpyencoder import NumpyEncoder

para resolver esse problema no 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()
krishna kumar mishra
fonte