Oznacza to, że gdzieś coś próbuje zrzucić tablicę numpy za pomocą jsonmodułu. Ale numpy.ndarraynie jest typem, który jsonwie, jak sobie z tym poradzić. Musisz albo napisać własny serializator, albo (prościej) po prostu przejść list(your_array)do tego, co pisze json.
mgilson
24
Uwaga list(your_array)nie zawsze będzie działać, ponieważ zwraca liczby całkowite numpy, a nie wartości wewnętrzne natywne. Użyj your_array.to_list()zamiast tego.
ashishsingal
18
uwaga na temat komentarza @ ashishsingal, powinna to być twoja_tablica.tolist (), a nie to_list ().
vega
Odpowiedzi:
289
Regularnie „jsonify” np. Tablice. Najpierw spróbuj użyć metody „.tolist ()” na tablicach:
import numpy as npimport codecs, json
a = np.arange(10).reshape(2,5)# a 2 by 5 array
b = a.tolist()# nested lists with same data, indices
file_path ="/path.json"## your path variable
json.dump(b, codecs.open(file_path,'w', encoding='utf-8'), separators=(',',':'), sort_keys=True, indent=4)### this saves the array in .json format
Dlaczego może być przechowywany tylko jako lista list?
Nikhil Prabhu
Nie wiem, ale spodziewam np.array typów metadanych, które nie pasuje do JSON (np one określić typ danych każdego wpisu jak float)
travelingbones
2
Próbowałem twojej metody, ale wygląda na to, że program utknął tolist().
Harvett,
3
@frankliuao znalazłem powód, który tolist()zajmuje dużo czasu, gdy dane są duże.
Harvett,
4
@NikhilPrabhu JSON jest JavaScript Object Notation, a zatem może reprezentować tylko podstawowe konstrukcje z języka javascript: obiekty (analogiczne do python dicts), tablice (analogiczne do list python), liczby, booleany, łańcuchy i null (analogiczne do python Nones ). Tablice Numpy nie są żadną z tych rzeczy, dlatego nie można ich przekształcić do postaci szeregowej w JSON. Niektóre można przekonwertować na formę podobną do JSO (lista list), co właśnie robi ta odpowiedź.
Chris L. Barnes,
225
Przechowuj jako JSON numpy.ndarray lub dowolną kompozycję listy zagnieżdżonej.
Ta odpowiedź jest świetna i można ją łatwo rozszerzyć, aby serializować wartości numpy float32 i np.float64 jako json:if isinstance(obj, np.float32) or isinstance(obj, np.float64): return float(obj)
Bensge
To rozwiązanie pozwala uniknąć ręcznego rzutowania każdej tablicy numpy na listę.
Dziękuję za pomocną odpowiedź! Zapisałem atrybuty do pliku json, ale mam teraz problemy z odczytaniem parametrów regresji logistycznej. Czy istnieje „dekoder” dla tego zapisanego pliku Json?
TTZ
Oczywiście, aby przeczytać odwrotną jsonstronę, możesz użyć tego with open(path, 'r') as f:data = json.load(f):, który zwraca słownik z Twoimi danymi.
tsveti_iko,
To jest do odczytu jsonpliku, a następnie do deserializacji jego danych wyjściowych, możesz użyć tego:data = json.loads(data)
tsveti_iko
Musiałem to dodać, aby obsłużyć typ danych bajtów .. zakładając, że wszystkie bajty są ciągiem utf-8. elif isinstance (obj, (bytes,)): return obj.decode ("utf-8")
Soichi Hayashi
+1. Dlaczego potrzebujemy wiersza „return json.JSONEncoder.default (self, obj)” na końcu „def default (self, obj)”?
Jaka jest tam rola linii type(obj).__module__ == np.__name__: ? Czy nie wystarczy sprawdzić instancję?
Ramon Martinez
@RamonMartinez, aby wiedzieć, że obiekt jest obiektem numpy, w ten sposób mogę użyć .itemdo prawie każdego obiektu numpy. defaultfunkcja jest wywoływana dla wszystkich json.dumpsprób serializacji nieznanych typów . nie tylko numpy
moshevi
5
To nie jest domyślnie obsługiwane, ale możesz sprawić, że będzie działać dość łatwo! Jest kilka rzeczy, które chcesz zakodować, jeśli chcesz odzyskać dokładnie te same dane:
Same dane, które można uzyskać obj.tolist()za pomocą wspomnianych @travelingbones. Czasami może to być wystarczająco dobre.
Typ danych Uważam, że jest to ważne w niektórych przypadkach.
Wymiar (niekoniecznie 2D), który można wyprowadzić z powyższego, zakładając, że dane wejściowe są rzeczywiście zawsze „prostokątną” siatką.
Kolejność pamięci (główny wiersz lub kolumna). To często nie ma znaczenia, ale czasami ma (np. Wydajność), więc dlaczego nie zapisać wszystkiego?
Ponadto tablica numpy może stanowić część struktury danych, np. Masz listę z pewnymi macierzami. W tym celu możesz użyć niestandardowego kodera, który zasadniczo robi powyższe.
To powinno wystarczyć do wdrożenia rozwiązania. Lub możesz użyć sztuczek json, które właśnie to robią (i obsługują różne inne typy) (zastrzeżenie: zrobiłem to).
pip install json-tricks
Następnie
data =[
arange(0,10,1, dtype=int).reshape((2,5)),
datetime(year=2017, month=1, day=19, hour=23, minute=00, second=00),1+2j,Decimal(42),Fraction(1,3),MyTestCls(s='ub', dct={'7':7}),# see later
set(range(7)),]# Encode with metadata to preserve types when decodingprint(dumps(data))
Miałem podobny problem z zagnieżdżonym słownikiem z kilkoma numpy.ndarrays.
def jsonify(data):
json_data = dict()for key, value in data.iteritems():if isinstance(value, list):# for lists
value =[ jsonify(item)if isinstance(item, dict)else item for item in value ]if isinstance(value, dict):# for nested lists
value = jsonify(value)if isinstance(key, int):# if key is integer: > to string
key = str(key)if type(value).__module__=='numpy':# if value is numpy.*: > to python list
value = value.tolist()
json_data[key]= value
return json_data
Można zauważyć, że kiedy przekonwertuję moje tablice na listę przed zapisaniem go w pliku JSON, w moim wdrożeniu i tak właśnie teraz, po przeczytaniu tego pliku JSON do użytku później, mogę nadal używać go w formie listy (jako zamiast konwertować go z powrotem do tablicy).
I faktycznie wygląda ładniej (moim zdaniem) na ekranie jako lista (rozdzielana przecinkami) w porównaniu do tablicy (rozdzielana przecinkami) w ten sposób.
Korzystając z powyższej metody .tolist () w @ travelbones, używałem jako takiej (wyłapałem kilka znalezionych błędów):
To inna odpowiedź, ale może to pomóc osobom, które próbują zapisać dane, a następnie przeczytać je ponownie.
Jest hickle, który jest szybszy niż marynowany i łatwiejszy.
Próbowałem zapisać i odczytać go na zrzutie pikli, ale podczas czytania było wiele problemów i zmarnowałem godzinę i wciąż nie znalazłem rozwiązania, chociaż pracowałem nad własnymi danymi, aby stworzyć bota czatu.
Błąd typu: tablica ([[0.46872085, 0.67374235, 1.0218339, 0.13210179, 0.5440686, 0.9140083, 0.58720225, 0.2199381]], dtype = float32) nie jest serializowalny w JSON
Wyżej wymieniony błąd został zgłoszony, gdy próbowałem przekazać listę danych do model.predict (), gdy oczekiwałem odpowiedzi w formacie json.
>1 json_file = open('model.json','r')>2 loaded_model_json = json_file.read()>3 json_file.close()>4 loaded_model = model_from_json(loaded_model_json)>5#load weights into new model>6 loaded_model.load_weights("model.h5")>7 loaded_model.compile(optimizer='adam', loss='mean_squared_error')>8 X =[[874,12450,678,0.922500,0.113569]]>9 d = pd.DataFrame(X)>10 prediction = loaded_model.predict(d)>11return jsonify(prediction)
Ale na szczęście udało się znaleźć wskazówkę dotyczącą rozwiązania zgłaszanego błędu. Serializacja obiektów ma zastosowanie tylko w przypadku następnej konwersji. Mapowanie powinno odbywać się w następujący sposób: obiekt - tablica dict - ciąg list - liczba całkowita string - liczba całkowita
Jeśli przewiniesz w górę, aby zobaczyć prognozę numer 10 = load_model.predict (d), gdzie ten wiersz kodu generował dane wyjściowe typu danych typu tablica, kiedy spróbujesz przekonwertować tablicę na format json, nie jest to możliwe
W końcu znalazłem rozwiązanie, konwertując uzyskane dane wyjściowe do listy typów za pomocą następujących wierszy kodu
json
modułu. Alenumpy.ndarray
nie jest typem, któryjson
wie, jak sobie z tym poradzić. Musisz albo napisać własny serializator, albo (prościej) po prostu przejśćlist(your_array)
do tego, co pisze json.list(your_array)
nie zawsze będzie działać, ponieważ zwraca liczby całkowite numpy, a nie wartości wewnętrzne natywne. Użyjyour_array.to_list()
zamiast tego.Odpowiedzi:
Regularnie „jsonify” np. Tablice. Najpierw spróbuj użyć metody „.tolist ()” na tablicach:
Aby „odrzucić” tablicę, użyj:
źródło
tolist()
.tolist()
zajmuje dużo czasu, gdy dane są duże.Przechowuj jako JSON numpy.ndarray lub dowolną kompozycję listy zagnieżdżonej.
Wyjdzie:
Aby przywrócić z JSON:
Wyjdzie:
źródło
numpy.asarray()
?if isinstance(obj, np.float32) or isinstance(obj, np.float64): return float(obj)
Możesz użyć pand :
źródło
pd.DataFrame(your_array).to_json('data.json', orient='split')
.Znalazłem najlepsze rozwiązanie, jeśli zagnieździłeś tablice numpy w słowniku:
Dzięki temu facetowi .
źródło
json
stronę, możesz użyć tegowith open(path, 'r') as f:
data = json.load(f)
:, który zwraca słownik z Twoimi danymi.json
pliku, a następnie do deserializacji jego danych wyjściowych, możesz użyć tego:data = json.loads(data)
Użyj
json.dumps
default
kwarga:W
default
funkcji sprawdź, czy obiekt pochodzi z modułu numpy, jeśli tak, użyj albondarray.tolist
a,ndarray
albo użyj.item
dowolnego innego typu numpy.źródło
type(obj).__module__ == np.__name__:
? Czy nie wystarczy sprawdzić instancję?.item
do prawie każdego obiektu numpy.default
funkcja jest wywoływana dla wszystkichjson.dumps
prób serializacji nieznanych typów . nie tylko numpyTo nie jest domyślnie obsługiwane, ale możesz sprawić, że będzie działać dość łatwo! Jest kilka rzeczy, które chcesz zakodować, jeśli chcesz odzyskać dokładnie te same dane:
obj.tolist()
za pomocą wspomnianych @travelingbones. Czasami może to być wystarczająco dobre.Ponadto tablica numpy może stanowić część struktury danych, np. Masz listę z pewnymi macierzami. W tym celu możesz użyć niestandardowego kodera, który zasadniczo robi powyższe.
To powinno wystarczyć do wdrożenia rozwiązania. Lub możesz użyć sztuczek json, które właśnie to robią (i obsługują różne inne typy) (zastrzeżenie: zrobiłem to).
Następnie
źródło
Miałem podobny problem z zagnieżdżonym słownikiem z kilkoma numpy.ndarrays.
źródło
Możesz także użyć
default
argumentu na przykład:źródło
Ponadto, kilka bardzo interesujących informacji na temat list vs. tablic w Python ~> Python List vs. Array - kiedy używać?
Można zauważyć, że kiedy przekonwertuję moje tablice na listę przed zapisaniem go w pliku JSON, w moim wdrożeniu i tak właśnie teraz, po przeczytaniu tego pliku JSON do użytku później, mogę nadal używać go w formie listy (jako zamiast konwertować go z powrotem do tablicy).
I faktycznie wygląda ładniej (moim zdaniem) na ekranie jako lista (rozdzielana przecinkami) w porównaniu do tablicy (rozdzielana przecinkami) w ten sposób.
Korzystając z powyższej metody .tolist () w @ travelbones, używałem jako takiej (wyłapałem kilka znalezionych błędów):
ZAPISZ SŁOWNIK
CZYTAJ SŁOWNIK
Mam nadzieję że to pomoże!
źródło
Oto implementacja, która działa dla mnie i usunęła wszystkie nans (zakładając, że są to proste obiekty (lista lub dyktowanie)):
źródło
To inna odpowiedź, ale może to pomóc osobom, które próbują zapisać dane, a następnie przeczytać je ponownie.
Jest hickle, który jest szybszy niż marynowany i łatwiejszy.
Próbowałem zapisać i odczytać go na zrzutie pikli, ale podczas czytania było wiele problemów i zmarnowałem godzinę i wciąż nie znalazłem rozwiązania, chociaż pracowałem nad własnymi danymi, aby stworzyć bota czatu.
vec_x
ivec_y
są tablicami numpy:Następnie wystarczy go przeczytać i wykonać operacje:
źródło
Może zrobić prostą pętlę ze sprawdzaniem typów:
źródło
użyj NumpyEncodera z powodzeniem przetworzy zrzut jsona. bez rzucania - tablica NumPy nie jest serializowana JSON
źródło
Błąd typu: tablica ([[0.46872085, 0.67374235, 1.0218339, 0.13210179, 0.5440686, 0.9140083, 0.58720225, 0.2199381]], dtype = float32) nie jest serializowalny w JSON
Wyżej wymieniony błąd został zgłoszony, gdy próbowałem przekazać listę danych do model.predict (), gdy oczekiwałem odpowiedzi w formacie json.
Ale na szczęście udało się znaleźć wskazówkę dotyczącą rozwiązania zgłaszanego błędu. Serializacja obiektów ma zastosowanie tylko w przypadku następnej konwersji. Mapowanie powinno odbywać się w następujący sposób: obiekt - tablica dict - ciąg list - liczba całkowita string - liczba całkowita
Jeśli przewiniesz w górę, aby zobaczyć prognozę numer 10 = load_model.predict (d), gdzie ten wiersz kodu generował dane wyjściowe typu danych typu tablica, kiedy spróbujesz przekonwertować tablicę na format json, nie jest to możliwe
W końcu znalazłem rozwiązanie, konwertując uzyskane dane wyjściowe do listy typów za pomocą następujących wierszy kodu
Bhoom! w końcu uzyskał oczekiwany wynik,
źródło