«TypeError: (Integer) n'est pas sérialisable JSON» lors de la sérialisation de JSON en Python?


163

J'essaie d'envoyer un dictionnaire simple à un fichier json à partir de python, mais je continue à recevoir le message "TypeError: 1425 n'est pas sérialisable JSON".

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

Si j'ajoute l'argument par défaut, alors il écrit, mais les valeurs entières sont écrites dans le fichier json sous forme de chaînes, ce qui n'est pas souhaitable.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))


1
Cela ne semble pas "dupliquer" cette question.

8
J'ai trouvé mon problème. Le problème était que mes entiers étaient en fait de type numpy.int64.
user1329894

@ user1329894 Publier comme solution / explication et fermeture automatique ..

-0 pour écrire une repro minimale qui ne reproduit pas réellement le bogue.
Russell Borogove

Réponses:


268

J'ai trouvé mon problème. Le problème était que mes entiers étaient en fait de type numpy.int64.


22
Je devais également traiter de cette question et votre réponse m'a orienté dans la bonne direction. Je voulais juste ajouter un lien vers une autre question qui peut aider à résoudre réellement le problème.
JAC

19
Ce serait bien si le message d'erreur JSON unserializable pouvait afficher le type de l'objet ...
Franck Dernoncourt

6
Voici une solution ordonnée qui utilise un sérialiseur personnalisé.
Owen

17
C'est ça le problème, mais quelle est la solution?
BallpointBen

5
x.astype (int) ou int (x)
zelcon

50

Il semble qu'il puisse y avoir un problème pour vider numpy.int64 dans la chaîne json dans Python 3 et l'équipe python a déjà une conversation à ce sujet. Plus de détails peuvent être trouvés ici .

Il existe une solution de contournement fournie par Serhiy Storchaka. Cela fonctionne très bien donc je le colle ici:

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

json.dumps({'value': numpy.int64(42)}, default=convert)

Une merveilleuse solution de contournement fournie par Serhiy. Veuillez vérifier son approche. Et pour ajouter, juste: json.dumps (yourObject, default = default); comme ici.
Pranzell le

4

Cela a résolu le problème pour moi:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }

4

Convertissez simplement les nombres de int64(de numpy) à int.

Par exemple, si la variable xest un int64:

int(x)

Si est un tableau de int64:

map(int, x)

3

comme @JAC l'a souligné dans les commentaires de la réponse la mieux notée, la solution générique (pour tous les types numpy) se trouve dans le fil de discussion Conversion de dtypes numpy en types python natifs .

Néanmoins, je vais ajouter ma version de la solution ci-dessous, car dans mon cas j'avais besoin d'une solution générique qui combine ces réponses et avec les réponses de l'autre fil. Cela devrait fonctionner avec presque tous les types numpy.

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

json.dumps({'value': numpy.int64(42)}, default=convert)

Belle réponse en effet
jtlz2

2

Cela pourrait être la réponse tardive, mais récemment, j'ai eu la même erreur. Après beaucoup de surf, cette solution m'a aidé.

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

Appel myconverterà json.dumps()comme ci - dessous.json.dumps(alerts, default=myconverter).


1

Vous pouvez également d'abord convertir votre objet en dataframe:

df = pd.DataFrame(obj)

puis enregistrez-le dataframedans un jsonfichier:

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

J'espère que cela t'aides



0

Même problème. La liste contenait des nombres de type numpy.int64 qui lève une TypeError. Une solution de contournement rapide pour moi était de

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

qui convertit la liste en str () et la fonction eval () évalue la «chaîne» comme une expression python et renvoie le résultat sous forme de liste d'entiers dans mon cas.


Je viens de remarquer que eval (str ()) est très lent, alors utilisez-le avec prudence. La réponse de @ shiva est bien meilleure: json.dumps (alertes, par défaut = myconverter)
user319436

0

utilisation

from numpyencoder import NumpyEncoder

pour résoudre ce problème dans 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()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.