„TypeError: (Integer) nie nadaje się do serializacji JSON” podczas serializacji JSON w Pythonie?

162

Próbuję wysłać prosty słownik do pliku json z języka Python, ale wciąż otrzymuję komunikat „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()

Jeśli dodam domyślny argument, to zapisuje, ale wartości całkowite są zapisywane w pliku json jako ciągi znaków, co jest niepożądane.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
user1329894
źródło
możliwy duplikat json.dump wyrzucający „TypeError: {...} nie jest
Shiplu Mokaddim
1
Wydaje się, że to nie „powiela” tego pytania ...
8
Znalazłem swój problem. Problem polegał na tym, że moje liczby całkowite były w rzeczywistości typu numpy.int64.
user1329894
@ user1329894 Opublikuj jako rozwiązanie / wyjaśnienie i samozamykanie ..
-0 za napisanie minimalnej reprodukcji, która w rzeczywistości nie odtwarza błędu.
Russell Borogove

Odpowiedzi:

268

Znalazłem swój problem. Problem polegał na tym, że moje liczby całkowite były w rzeczywistości typem numpy.int64.

user1329894
źródło
22
Ja też musiałem poradzić sobie z tą kwestią, a Twoja odpowiedź wskazała mi właściwy kierunek. Chciałem tylko dodać link do innego pytania, które może pomóc w rzeczywistym rozwiązaniu problemu.
JAC
19
Byłoby miło, gdyby komunikat błędu JSON unserializable mógł wyświetlać typ obiektu ...
Franck Dernoncourt
6
Oto schludne rozwiązanie, które używa niestandardowego serializatora.
Owen
17
To jest problem, ale jakie jest rozwiązanie?
BallpointBen
5
x.astype (int) lub int (x)
zelcon
50

Wygląda na to, że może wystąpić problem z wrzuceniem numpy.int64 do łańcucha json w Pythonie 3 i zespół pythona już o tym rozmawia. Więcej szczegółów można znaleźć tutaj .

Istnieje obejście dostarczone przez Serhiya Storchakę. Działa bardzo dobrze, więc wklejam go tutaj:

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

json.dumps({'value': numpy.int64(42)}, default=convert)
hsc
źródło
Wspaniałe obejście dostarczone przez Serhiya. Sprawdź jego podejście. Aby dodać, po prostu: json.dumps (yourObject, default = default); jak tutaj.
Pranzell
4

To rozwiązało problem dla mnie:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }
Tobias Ernst
źródło
4

Po prostu przekonwertuj liczby z int64(z numpy) na int.

Na przykład, jeśli zmienna xto int64:

int(x)

Jeśli jest tablicą int64:

map(int, x)
Jonatas Eduardo
źródło
3

jak @JAC zauważył w komentarzach do najwyżej ocenionych odpowiedzi, ogólne rozwiązanie (dla wszystkich typów numpy) można znaleźć w wątku Konwersja numpy dtypes na natywne typy Pythona .

Niemniej jednak dodam poniżej moją wersję rozwiązania, ponieważ w moim przypadku potrzebowałem ogólnego rozwiązania, które łączy te odpowiedzi z odpowiedziami z drugiego wątku. To powinno działać z prawie wszystkimi typami numpy.

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

json.dumps({'value': numpy.int64(42)}, default=convert)
Powozik
źródło
Naprawdę
dobra
2

To może być późna odpowiedź, ale ostatnio dostałem ten sam błąd. Po długim surfowaniu pomogło mi to rozwiązanie.

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

Zadzwoń myconverterw json.dumps()jak poniżej.json.dumps(alerts, default=myconverter).

siedmiodniowa żałoba
źródło
1

Alternatywnie możesz najpierw przekształcić swój obiekt w ramkę danych:

df = pd.DataFrame(obj)

a następnie zapisz to dataframew jsonpliku:

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

Mam nadzieję że to pomoże

kartik
źródło
0

Masz Numpy Typ danych, po prostu zmień typ danych na normalny int () lub float (). będzie działać dobrze.

Sriram Arvind Lakshmanakumar
źródło
0

Taki sam problem. Lista zawiera liczby typu numpy.int64, które generują błąd TypeError. Szybkim rozwiązaniem było dla mnie

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

która konwertuje listę na str () i funkcję eval () oblicza „String” jak wyrażenie w Pythonie i zwraca wynik jako listę liczb całkowitych w moim przypadku.

user319436
źródło
Właśnie zauważyłem, że eval (str ()) jest bardzo powolny, więc używaj go ostrożnie. Odpowiedź @ shiva jest znacznie lepsza: json.dumps (alerts, default = myconverter)
user319436
0

posługiwać się

from numpyencoder import NumpyEncoder

aby rozwiązać ten problem w 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
źródło