NumPy 배열은 JSON 직렬화 가능하지 않습니다
NumPy 배열을 만들고 장고 컨텍스트 변수로 저장 한 후 웹 페이지를로드 할 때 다음 오류가 발생합니다.
array([ 0, 239, 479, 717, 952, 1192, 1432, 1667], dtype=int64) is not JSON serializable
이것은 무엇을 의미 하는가?
나는 정기적으로 np.arrays를 "jsonify"합니다. 먼저 다음과 같이 배열에서 ".tolist ()"메소드를 사용해보십시오.
import numpy as np
import 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
배열을 "unjsonify"하려면 다음을 사용하십시오.
obj_text = codecs.open(file_path, 'r', encoding='utf-8').read()
b_new = json.loads(obj_text)
a_new = np.array(b_new)
JSON으로 numpy.ndarray 또는 중첩 목록 구성을 저장하십시오.
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
json_dump = json.dumps({'a': a, 'aa': [2, (2, 3, 4), a], 'bb': [2]}, cls=NumpyEncoder)
print(json_dump)
출력합니다 :
(2, 3)
{"a": [[1, 2, 3], [4, 5, 6]], "aa": [2, [2, 3, 4], [[1, 2, 3], [4, 5, 6]]], "bb": [2]}
JSON에서 복원하려면
json_load = json.loads(json_dump)
a_restored = np.asarray(json_load["a"])
print(a_restored)
print(a_restored.shape)
출력합니다 :
[[1 2 3]
[4 5 6]]
(2, 3)
팬더 를 사용할 수 있습니다 :
import pandas as pd
pd.Series(your_array).to_json(orient='values')
사전에 numpy 배열을 중첩하면 가장 좋은 해결책을 찾았습니다.
import json
import numpy as np
class NumpyEncoder(json.JSONEncoder):
""" Special json encoder for numpy types """
def default(self, obj):
if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
np.int16, np.int32, np.int64, np.uint8,
np.uint16, np.uint32, np.uint64)):
return int(obj)
elif isinstance(obj, (np.float_, np.float16, np.float32,
np.float64)):
return float(obj)
elif isinstance(obj,(np.ndarray,)): #### This is the fix
return obj.tolist()
return json.JSONEncoder.default(self, obj)
dumped = json.dumps(data, cls=NumpyEncoder)
with open(path, 'w') as f:
json.dump(dumped, f)
이 사람 에게 감사합니다 .
다른 numpy 엔코더 중 일부는 약간 지나치게 장황하게 보입니다.
json.dumps
default
kwarg를 사용하십시오 .
기본값은 직렬화 할 수없는 객체에 대해 호출되는 함수 여야합니다.
에서 default
기능 검사 대상물이 모듈에서 NumPy와이면 어느 용도 그렇다면 ndarray.tolist
A에 대한 ndarray
사용하거나 .item
다른 NumPy와의 특정 유형.
import numpy as np
def default(obj):
if type(obj).__module__ == np.__name__:
if isinstance(obj, np.ndarray):
return obj.tolist()
else:
return obj.item()
raise TypeError('Unknown type:', type(obj))
dumped = json.dumps(data, default=default)
이 기능은 기본적으로 지원되지 않지만 매우 쉽게 작동 할 수 있습니다! 똑같은 데이터를 다시 원한다면 인코딩하고 싶은 것이 몇 가지 있습니다.
obj.tolist()
@travelingbones가 언급 한대로 얻을 수있는 데이터 자체 . 때로는 이것으로 충분할 수 있습니다.- 데이터 타입. 나는 이것이 매우 중요한 경우라고 생각합니다.
- 입력이 항상 '직사각형'그리드라고 가정하면 위로부터 파생 될 수있는 치수 (2D 일 필요는 없음)입니다.
- 메모리 순서 (행 또는 열 주요). 이것은 종종 중요하지 않지만 때로는 중요합니다 (예 : 성능). 왜 모든 것을 저장하지 않습니까?
Furthermore, your numpy array could part of your data structure, e.g. you have a list with some matrices inside. For that you could use a custom encoder which basically does the above.
This should be enough to implement a solution. Or you could use json-tricks which does just this (and supports various other types) (disclaimer: I made it).
pip install json-tricks
Then
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 decoding
print(dumps(data))
I had a similar problem with a nested dictionary with some numpy.ndarrays in it.
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
You could also use default
argument for example:
def myconverter(o):
if isinstance(o, np.float32):
return float(o)
json.dump(data, default=myconverter)
Also, some very interesting information further on lists vs. arrays in Python ~> Python List vs. Array - when to use?
It could be noted that once I convert my arrays into a list before saving it in a JSON file, in my deployment right now anyways, once I read that JSON file for use later, I can continue to use it in a list form (as opposed to converting it back to an array).
AND actually looks nicer (in my opinion) on the screen as a list (comma seperated) vs. an array (not-comma seperated) this way.
Using @travelingbones's .tolist() method above, I've been using as such (catching a few errors I've found too):
SAVE DICTIONARY
def writeDict(values, name):
writeName = DIR+name+'.json'
with open(writeName, "w") as outfile:
json.dump(values, outfile)
READ DICTIONARY
def readDict(name):
readName = DIR+name+'.json'
try:
with open(readName, "r") as infile:
dictValues = json.load(infile)
return(dictValues)
except IOError as e:
print(e)
return('None')
except ValueError as e:
print(e)
return('None')
Hope this helps!
Here is an implementation that work for me and removed all nans (assuming these are simple object (list or dict)):
from numpy import isnan
def remove_nans(my_obj, val=None):
if isinstance(my_obj, list):
for i, item in enumerate(my_obj):
if isinstance(item, list) or isinstance(item, dict):
my_obj[i] = remove_nans(my_obj[i], val=val)
else:
try:
if isnan(item):
my_obj[i] = val
except Exception:
pass
elif isinstance(my_obj, dict):
for key, item in my_obj.iteritems():
if isinstance(item, list) or isinstance(item, dict):
my_obj[key] = remove_nans(my_obj[key], val=val)
else:
try:
if isnan(item):
my_obj[key] = val
except Exception:
pass
return my_obj
This is a different answer, but this might help to help people who are trying to save data and then read it again.
There is hickle which is faster than pickle and easier.
I tried to save and read it in pickle dump but while reading there were lot of problems and wasted an hour and still didn't find solution though I was working on my own data to create a chat bot.
vec_x
and vec_y
are numpy arrays:
data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )
Then you just read it and perform the operations:
data2 = hkl.load( 'new_data_file.hkl' )
May do simple for loop with checking types:
with open("jsondontdoit.json", 'w') as fp:
for key in bests.keys():
if type(bests[key]) == np.ndarray:
bests[key] = bests[key].tolist()
continue
for idx in bests[key]:
if type(bests[key][idx]) == np.ndarray:
bests[key][idx] = bests[key][idx].tolist()
json.dump(bests, fp)
fp.close()
TypeError: array([[0.46872085, 0.67374235, 1.0218339 , 0.13210179, 0.5440686 , 0.9140083 , 0.58720225, 0.2199381 ]], dtype=float32) is not JSON serializable
The above-mentioned error was thrown when i tried to pass of list of data to model.predict() when i was expecting the response in json format.
> 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)
> 11 return jsonify(prediction)
But luckily found the hint to resolve the error that was throwing The serializing of the objects is applicable only for the following conversion Mapping should be in following way object - dict array - list string - string integer - integer
If you scroll up to see the line number 10 prediction = loaded_model.predict(d) where this line of code was generating the output of type array datatype , when you try to convert array to json format its not possible
Finally i found the solution just by converting obtained output to the type list by following lines of code
prediction = loaded_model.predict(d)
listtype = prediction.tolist() return jsonify(listtype)
Bhoom! finally got the expected output,
참고URL : https://stackoverflow.com/questions/26646362/numpy-array-is-not-json-serializable
'Programing' 카테고리의 다른 글
Workbench를 사용하여 서버에서 데이터베이스의 ER 모델을 얻는 방법 (0) | 2020.05.16 |
---|---|
몽구스 문서를 어떻게 일반 객체로 바꾸나요? (0) | 2020.05.16 |
UIButton : 적중 영역을 기본 적중 영역보다 크게 만들기 (0) | 2020.05.16 |
배열의 첫 번째 N 요소를 얻습니까? (0) | 2020.05.15 |
Python Pandas 명시 적으로 열을 나열하지 않고 DataFrame에서 하나 이상의 null이있는 행을 선택하는 방법은 무엇입니까? (0) | 2020.05.15 |