"TypeError: (Integer) ist nicht JSON-serialisierbar" beim Serialisieren von JSON in Python?

162

Ich versuche, ein einfaches Wörterbuch von Python an eine JSON-Datei zu senden, erhalte jedoch weiterhin die Meldung "TypeError: 1425 ist nicht JSON-serialisierbar".

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

Wenn ich das Standardargument hinzufüge, schreibt es, aber die ganzzahligen Werte werden als Zeichenfolgen in die JSON-Datei geschrieben, was unerwünscht ist.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
user1329894
quelle
1
Dies scheint diese Frage nicht zu "duplizieren".
8
Ich habe mein Problem gefunden. Das Problem war, dass meine ganzen Zahlen tatsächlich vom Typ numpy.int64 waren.
user1329894
@ user1329894 Post als Lösung / Erklärung und selbst schließen ..
-0 für das Schreiben eines minimalen Repro, der den Fehler nicht wirklich reproduziert.
Russell Borogove

Antworten:

268

Ich habe mein Problem gefunden. Das Problem war, dass meine ganzen Zahlen tatsächlich Typ waren numpy.int64.

user1329894
quelle
22
Ich musste mich auch mit diesem Thema befassen, und Ihre Antwort zeigte mir die richtige Richtung. Ich wollte nur einen Link zu einer anderen Frage hinzufügen , die bei der tatsächlichen Lösung des Problems helfen kann.
JAC
19
Das wäre schön, wenn die unserialisierbare JSON-Fehlermeldung den Typ des Objekts anzeigen könnte ...
Franck Dernoncourt
6
Hier ist eine ordentliche Lösung, die einen benutzerdefinierten Serializer verwendet.
Owen
17
Das ist das Problem, aber was ist die Lösung?
BallpointBen
5
x.astype (int) oder int (x)
zelcon
50

Es scheint ein Problem zu geben, numpy.int64 in Python 3 in json string zu speichern, und das Python-Team hat bereits ein Gespräch darüber. Weitere Details finden Sie hier .

Es gibt eine Problemumgehung, die von Serhiy Storchaka bereitgestellt wird. Es funktioniert sehr gut, also füge ich es hier ein:

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

json.dumps({'value': numpy.int64(42)}, default=convert)
hsc
quelle
Eine wunderbare Problemumgehung von Serhiy. Bitte überprüfen Sie seinen Ansatz. Und zum Hinzufügen einfach: json.dumps (yourObject, default = default); wie hier.
Pranzell
4

Dies löste das Problem für mich:

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

Konvertieren Sie einfach Zahlen von int64(von numpy) nach int.

Wenn die Variable xbeispielsweise ein int64 ist:

int(x)

If ist ein Array von int64:

map(int, x)
Jonatas Eduardo
quelle
3

Wie @JAC in den Kommentaren der am höchsten bewerteten Antwort hervorhob, finden Sie die generische Lösung (für alle Numpy-Typen) im Thread Konvertieren von Numpy-D-Typen in native Python-Typen .

Trotzdem werde ich meine Version der Lösung unten hinzufügen, da ich in meinem Fall eine generische Lösung brauchte, die diese Antworten mit den Antworten des anderen Threads kombiniert. Dies sollte mit fast allen Numpy-Typen funktionieren.

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

json.dumps({'value': numpy.int64(42)}, default=convert)
Buggy
quelle
Tatsächlich eine gute
2

Dies könnte die späte Antwort sein, aber kürzlich habe ich den gleichen Fehler erhalten. Nach vielem Surfen hat mir diese Lösung geholfen.

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

Rufen Sie myconverterin json.dumps()wie unten.json.dumps(alerts, default=myconverter).

Shiva
quelle
1

Alternativ können Sie Ihr Objekt zuerst in einen Datenrahmen konvertieren:

df = pd.DataFrame(obj)

und speichern Sie dies dataframein einer jsonDatei:

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

Hoffe das hilft

kartik
quelle
0

Sie haben den Numpy-Datentyp. Wechseln Sie einfach zum normalen Datentyp int () oder float (). es wird gut funktionieren.

Sriram Arvind Lakshmanakumar
quelle
0

Gleiches Problem. Liste enthielt Nummern vom Typ numpy.int64, die einen TypeError auslösen. Schnelle Problemumgehung für mich war zu

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

Die Funktion list in list (str () und eval () konvertiert den „String“ wie einen Python-Ausdruck und gibt das Ergebnis in meinem Fall als Liste von Ganzzahlen zurück.

user319436
quelle
Gerade bemerkt, dass eval (str ()) sehr langsam ist, also mit Vorsicht verwenden. @ shivas Antwort ist viel besser: json.dumps (Warnungen, Standard = myconverter)
user319436
0

verwenden

from numpyencoder import NumpyEncoder

So beheben Sie dieses Problem in 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
quelle