programing

NumPy 어레이는 JSON을 직렬화할 수 없습니다.

firstcheck 2022. 9. 19. 21:09
반응형

NumPy 어레이는 JSON을 직렬화할 수 없습니다.

NumPy 어레이를 생성하여 Django 컨텍스트 변수로 저장한 후 웹 페이지를 로드할 때 다음 오류가 나타납니다.

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

어레이의 「정합 해제」를 실시하려면 , 다음의 조작을 실시합니다.

obj_text = codecs.open(file_path, 'r', encoding='utf-8').read()
b_new = json.loads(obj_text)
a_new = np.array(b_new)

numpy.ndarray 또는 모든 중첩 목록 구성을 JSON으로 저장합니다.

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)

남자 덕분에.

팬더를 사용할 수 있습니다.

import pandas as pd
pd.Series(your_array).to_json(orient='values')

하다를 사용하세요.json.dumps default 동작:

기본값은 직렬화할 수 없는 개체에 대해 호출되는 함수여야 합니다. ... 또는 TypeError를 발생시킬 수 없습니다.

서서 default객체가 모듈 numpy에서 온 것인지 여부를 function 체크합니다.이 경우 다음 중 하나를 에 사용합니다.ndarray 「」를 사용합니다..item하다

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()@bones ( 서에 ) 。가끔은 이 정도면 충분할 수도 있어요.
  • 데이터 타입어떤 경우에는 이것이 중요하다고 생각합니다.
  • 입력이 실제로 항상 '직각' 그리드라고 가정할 경우 위에서 도출할 수 있는 치수(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.narrays가 포함된 중첩된 사전에서도 비슷한 문제가 있었습니다.

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

,도할 수 .default예를 들어 다음과 같습니다.

def myconverter(o):
    if isinstance(o, np.float32):
        return float(o)

json.dump(data, default=myconverter)

또한 Python의 목록과 어레이에 대한 자세한 내용은 Python의 ~> Python 목록과 어레이 - 언제 사용합니까?

어레이를 JSON 파일에 저장하기 전에 목록으로 변환하면 현재 전개 중인 JSON 파일을 나중에 사용하기 위해 읽으면 어레이로 다시 변환하는 것이 아니라 목록 형식으로 계속 사용할 수 있습니다.

또, 실제로 화면에서는, 리스트(콤마 구분)와 어레이(콤마 구분 없음)로 표시되는 것이 보다 보기 좋게 보입니다.

위의 @travingbones의 .tolist() 메서드를 사용하여 다음과 같이 사용하고 있습니다(몇 가지 오류도 발견).

사전 저장

def writeDict(values, name):
    writeName = DIR+name+'.json'
    with open(writeName, "w") as outfile:
        json.dump(values, outfile)

사전을 읽다

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')

이게 도움이 됐으면 좋겠네요!

NumpyEncoder를 사용하면 json 덤프가 정상적으로 처리됩니다.NumPy 어레이는 JSON을 시리얼화할 수 없습니다.

import numpy as np
import json
from numpyencoder import NumpyEncoder
arr = array([   0,  239,  479,  717,  952, 1192, 1432, 1667], dtype=int64) 
json.dumps(arr,cls=NumpyEncoder)

다음으로 모든 nan을 삭제한 실장을 나타냅니다(단순한 오브젝트(list 또는 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

이는 다른 답변이지만 데이터를 저장하고 다시 읽으려는 사용자에게 도움이 될 수 있습니다.
는 더 빨리 피클보다고 쉽게 hickle 있다.
나는 피클 쓰레기 더미에서 그것을 읽을 구할 수 없지만 책을 읽으면서 문제들이 많고 한시간을 낭비했다, 그리고 나는 나만의 데이터에 대한 채팅 봇을 짓는 일은 여전히 해결책을 찾지 않았다.

vec_x그리고.vec_y있numpy 배열:

data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )

그런 다음 내용을 읽고 작업을 수행합니다.

data2 = hkl.load( 'new_data_file.hkl' )

체크 타입을 사용한 루프의 경우는, 심플하게 할 수 있습니다.

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.140179, 0.5440686, 0.9140083, 0.58720225, 0.2199381]), dtype=1832)는 JSON 시리얼이 아닙니다.

위의 오류는 json 형식의 응답을 기대하고 있을 때 model.predict()에 데이터 목록을 전달하려고 했을 때 발생하였습니다.

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

그러나 다행히 오류를 해결하기 위한 힌트를 찾았습니다. 개체의 직렬화는 다음 변환에만 적용됩니다. 매핑은 개체 - dict 배열 - list string - string - integer - integer - integer로 해야 합니다.

위로 스크롤하여 10번 예측 = loaded_model.model(d) 행을 확인한 경우 이 줄의 코드가 type array datype 출력을 생성하고 있으면 어레이를 json 형식으로 변환할 수 없습니다.

마침내 나는 코드 줄을 따라 얻어진 출력을 유형 목록으로 변환하는 것만으로 해결책을 찾았다.

예측 = loaded_model.model(d)
listtype = 예측입니다.tolist()는 jsonify(listtype)를 반환합니다.

흥! 드디어 예상한 결과를 얻었네요.

언급URL : https://stackoverflow.com/questions/26646362/numpy-array-is-not-json-serializable

반응형