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)
답변
답변
사전에 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.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
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)
이 사람 에게 감사합니다 .
답변
json.dumps defaultkwarg를 사용하십시오 .
default는 달리 직렬화 할 수없는 객체에 대해 호출되는 함수 여야합니다.
에서 default기능 검사 대상물이 모듈에서 NumPy와이면 어느 용도 그렇다면 ndarray.tolistA에 대한 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 일 필요는 없음)입니다.
- 메모리 순서 (행 또는 열 주요). 이것은 종종 중요하지 않지만 때로는 중요합니다 (예 : 성능). 왜 모든 것을 저장하지 않습니까?
또한 numpy 배열은 데이터 구조의 일부일 수 있습니다. 예를 들어 일부 행렬이 포함 된 목록이 있습니다. 이를 위해 기본적으로 위의 작업을 수행하는 사용자 지정 인코더를 사용할 수 있습니다.
솔루션을 구현하기에 충분해야합니다. 또는이 작업 을 수행하고 다양한 다른 유형을 지원하는 json-tricks 를 사용할 수 있습니다 (면책 조항 : 내가 만들었습니다).
pip install json-tricks
그때
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))
답변
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
