numpy 유형을 python으로 변환
팬더에게서 생성되는 다음과 같은 형태의 딕트 목록이 있습니다.json 형식으로 변환하고 싶습니다.
list_val = [{1.0: 685}, {2.0: 8}]
output = json.dumps(list_val)
단, json.dumps는 다음 오류를 발생시킵니다.TypeError: 685는 JSON 시리얼화 불가
아마 numpy에서 python(?)으로의 타입 변환 문제일 것입니다.
그러나 np.int32(v)를 사용하여 어레이 내의 각 dict 값 v를 변환해도 오류가 발생합니다.
EDIT: 풀 코드입니다.
new = df[df[label] == label_new]
ks_dict = json.loads(content)
ks_list = ks_dict['variables']
freq_counts = []
for ks_var in ks_list:
freq_var = dict()
freq_var["name"] = ks_var["name"]
ks_series = new[ks_var["name"]]
temp_df = ks_series.value_counts().to_dict()
freq_var["new"] = [{u: np.int32(v)} for (u, v) in temp_df.iteritems()]
freq_counts.append(freq_var)
out = json.dumps(freq_counts)
당신 말이 맞는 것 같군요.
>>> import numpy
>>> import json
>>> json.dumps(numpy.int32(685))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 685 is not JSON serializable
여기서 안타까운 점은 숫자가 너무 많다는 것이다.__repr__
어떤 타입인지 힌트는 주지 않습니다.놈들은 놈들을 속이고 돌아다닌다닌가?int
s가 아닌 경우(실행하지 않은 경우).궁극적으로, 그것은json
그 말은int
serializable은 아니지만, 실제로는 이 특정 np.int32(또는 실제로 가지고 있는 타입)는 serializable이 아님을 나타내고 있습니다.(놀랄 일도 아닙니다.No np.int32는 시리얼화 가능합니다).이 때문에, 전달하기 전에 필연적으로 인쇄한 dict도,json.dumps
정수도 들어 있는 것 같아요
여기서 가장 쉬운 회피책은 아마도 자체 시리얼라이저를1 작성하는 것입니다.
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, numpy.integer):
return int(obj)
elif isinstance(obj, numpy.floating):
return float(obj)
elif isinstance(obj, numpy.ndarray):
return obj.tolist()
else:
return super(MyEncoder, self).default(obj)
다음과 같이 사용합니다.
json.dumps(numpy.float32(1.2), cls=MyEncoder)
json.dumps(numpy.arange(12), cls=MyEncoder)
json.dumps({'a': numpy.int32(42)}, cls=MyEncoder)
기타.
1또는 기본 함수를 쓰고 그것을 전달해 줄 수 있습니다.defaut
키워드 인수json.dumps
이 시나리오에서는 마지막 행을 다음과 같이 바꿉니다.raise TypeError
하지만... 어...클래스의 확장성이 향상되었습니다:-)
어레이를 파이썬 목록으로 변환할 수도 있습니다(tolist
method)를 사용하여 목록을 json으로 변환합니다.
NumPy int64에 대응하기 위해 ujson 포크를 사용할 수 있습니다.caiyunapp/caijson: Python 바인딩 및 NumPy 바인딩으로 C로 작성된 초고속 JSON 디코더 및 인코더
pip install nujson
그리고나서
>>> import numpy as np
>>> import nujson as ujson
>>> a = {"a": np.int64(100)}
>>> ujson.dumps(a)
'{"a":100}'
>>> a["b"] = np.float64(10.9)
>>> ujson.dumps(a)
'{"a":100,"b":10.9}'
>>> a["c"] = np.str_("12")
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12"}'
>>> a["d"] = np.array(list(range(10)))
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9]}'
>>> a["e"] = np.repeat(3.9, 4)
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9],"e":[3.9,3.9,3.9,3.9]}'
데이터 중 하나에 남겨두면pandas
오브젝트, 라이브러리가 제공하는to_json
Series, DataFrame 및 기타 모든 고차원 사촌에서 작동합니다.
경우에 따라서는 간단함json.dump(eval(str(a)), your_file)
도와준다.
변환할 numpy 숫자만 있는 경우 가장 쉬운 방법은 다음과 같습니다.
json.dumps(a, default=float)
dict가 ndarray 또는 float32 개체와 같은 여러 numpy 개체로 구성되어 있는 경우 ndarray를 수동으로 목록으로 변환할 수 있습니다..tolist()
import numpy as np
import json
a = np.empty([2, 2], dtype=np.float32)
json.dumps(a.tolist()) # this should work
또는 float32 개체를 저장하기 위해.item()
.
import numpy as np
import json
a = np.float32(1)
json.dumps(a.item()) # this should work
그러나 여러 개의 dict가 numpy 객체로 중첩된 목록에 중첩된 복잡한 dict가 있는 경우 코드를 탐색하고 각 변수를 수동으로 업데이트해야 하는 번거로움이 생깁니다.대신 json.dumps() 참조 중에 이를 처리하는 NumpyEncoder 클래스를 정의할 수 있습니다.
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.float32):
return obj.item()
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
with open('output.json', 'w') as outfile:
json.dump(json_dict, outfile, sort_keys=True, indent=4, cls=NumpyEncoder) # indent and sort_keys are just for cleaner output
이 방법은 완벽하게 작동했습니다. JSON 예제에 저장할 때 다른 데이터 유형을 처리할 수도 있고 저장할 때 소수 자릿수 형식을 지정할 수도 있습니다.
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, float):
return "{:.2f}".format(obj)
return json.JSONEncoder.default(self, obj)
언급URL : https://stackoverflow.com/questions/27050108/convert-numpy-type-to-python
'it-source' 카테고리의 다른 글
Backbone.js REST 콜에 대해서 (0) | 2023.02.22 |
---|---|
유형 선언의 @typescript-eslint/no-discript-false positive false 긍정 (0) | 2023.02.22 |
커스텀 포스트 wp_pagnation (0) | 2023.02.22 |
iis7의 워드프레스 URL에서 index.php를 제거합니다. (0) | 2023.02.22 |
JSON을 소독할 필요가 있습니까? (0) | 2023.02.22 |