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
default
kwarg를 사용하십시오 .
default는 달리 직렬화 할 수없는 객체에 대해 호출되는 함수 여야합니다.
에서 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 일 필요는 없음)입니다.
- 메모리 순서 (행 또는 열 주요). 이것은 종종 중요하지 않지만 때로는 중요합니다 (예 : 성능). 왜 모든 것을 저장하지 않습니까?
또한 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