«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))
user1329894
la source
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.

user1329894
la source
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)
hsc
la source
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)
    }
Tobias Ernst
la source
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)
Jonatas Eduardo
la source
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)
Petit chariot
la source
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).

Shiva
la source
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

kartik
la source
0

Vous avez le type de données Numpy, il suffit de passer au type de données normal int () ou float (). cela fonctionnera très bien.

Sriram Arvind Lakshmanakumar
la source
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.

user319436
la source
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()
Krishna Kumar Mishra
la source