대신 Python JSON 인코더는 NaN을 null로 변환합니다.
JSON으로 변환할 수 있는 임의의 오브젝트(내스트 가능성이 있음)를 수신하기 위해 코드를 쓰고 있습니다.
의 기본 를 Python으로 변환하는 것입니다.NaN
예 , ) 。json.dumps(np.NaN)
이 되다NaN
하면 이 '이러다'를 수 있을까요NaN
을 매기다null
다음과 같이 메서드를 하위 분류하고 재정의하려고 했습니다.
from json import JSONEncoder, dumps
import numpy as np
class NanConverter(JSONEncoder):
def default(self, obj):
try:
_ = iter(obj)
except TypeError:
if isinstance(obj, float) and np.isnan(obj):
return "null"
return JSONEncoder.default(self, obj)
>>> d = {'a': 1, 'b': 2, 'c': 3, 'e': np.nan, 'f': [1, np.nan, 3]}
>>> dumps(d, cls=NanConverter)
'{"a": 1, "c": 3, "b": 2, "e": NaN, "f": [1, NaN, 3]}'
결과: ★★★★★★★★★★★★★★★★★★★★★★★:'{"a": 1, "c": 3, "b": 2, "e": null, "f": [1, null, 3]}'
이것으로 내 목표는 달성된 것 같다.
import simplejson
>>> simplejson.dumps(d, ignore_nan=True)
Out[3]: '{"a": 1, "c": 3, "b": 2, "e": null, "f": [1, null, 3]}'
@와 같이는 @Gerrat입니다.
dumps(d, cls=NanConverter)
불행히도 효과가 없을 거야@Alexander's
simplejson.dumps(d, ignore_nan=True)
하지만, 생깁니다(동작, 「 」simplejson
를 참조해 주세요.
다른 의존관계(판다)를 도입하는 경우:
또 하나의 명백한 해결책은
dumps(pd.DataFrame(d).fillna(None))
, 그러나 판다들은 1972년 발행한다.d.fillna(None)
에는 예측할수 없는 동작이 할 수 없습니다.:
fillna(None)
fillna()
이는 값 파라미터가 사용되지 않음을 의미합니다.대신 기본적으로 순방향 채우기인 메서드 매개 변수를 사용합니다.대신 신을 .
DataFrame.where
:df = pd.DataFrame(d) dumps(df.where(pd.notnull(df), None)))
아쉽게도 @Bramar의 제안을 사용해야 할 것 같습니다.당신은 이것을 직접 사용할 수 없을 거예요.Python의 JSON 인코더용 문서에는 다음과 같이 기술되어 있습니다.
지정한 경우 기본값은 직렬화할 수 없는 개체에 대해 호출되는 함수입니다.
의 ★★★★★★★★★★★★★★★★★.NanConverter.default
Python의 JSON 인코더는 이미 시리얼화 방법을 알고 있기 때문에 메서드는 호출조차 되지 않습니다.np.nan
문구를 추가합니다.알 수 . 몇 가지 로깅/인쇄 문구를 추가합니다.메서드가 호출되지도 않았음을 알 수 있습니다.
는 결국 이 일을 하게 되었다.encode
★★★★★★★★★★★★★★★★★」iterencode
의 NanConverter
''', '''obj
nan
로로 합니다.None
은 (그것은)가 될 이다.null
(일본어)
@Gerrat가 지적했듯이 Python JSONncoder는 호출하지 않습니다.default
when 를 만났을 때nan
★★★★★★★★★★★★★★★★★★★★★★★dump
/dumps
allow_nan=False
사용자에게 "자신의 일을 할 수 있는" 기회를 주기 전에 예외를 발생시킵니다.
import math
import numpy as np
from json import JSONEncoder, dumps
def nan2None(obj):
if isinstance(obj, dict):
return {k:nan2None(v) for k,v in obj.items()}
elif isinstance(obj, list):
return [nan2None(v) for v in obj]
elif isinstance(obj, float) and math.isnan(obj):
return None
return obj
class NanConverter(JSONEncoder):
def default(self, obj):
# possible other customizations here
pass
def encode(self, obj, *args, **kwargs):
obj = nan2None(obj)
return super().encode(obj, *args, **kwargs)
def iterencode(self, obj, *args, **kwargs):
obj = nan2None(obj)
return super().iterencode(obj, *args, **kwargs)
>>> d = {'a': 1, 'b': 2, 'c': 3, 'e': math.nan, 'f': [1, np.nan, 3]}
>>> dumps(d, cls=NanConverter)
'{"a": 1, "b": 2, "c": 3, "e": null, "f": [1, null, 3]}'
여기서 simplejson은 적절한 작업을 수행할 수 있지만 다음과 같은 추가 플래그가 있습니다.
simplejson을 사용해 보십시오.
pip install simplejson
그 후 코드:
import simplejson
response = df.to_dict('records')
simplejson.dumps(response, ignore_nan=True,default=datetime.datetime.isoformat)
ignore_nan 플래그는 모든 NaN --> 늘 변환을 올바르게 처리합니다.
기본 플래그를 사용하면 simplejson이 데이터 시간을 올바르게 구문 분석할 수 있습니다.
팬더 사용
Panda를 사용하는 사용자에게 가장 간단한 방법 - 서드파티 라이브러리가 필요하지 않습니다. df.to_json.NaN 및 기타 Numpy 유형도 네스트 구조로 변환됩니다.
df = pd.DataFrame({
'words': ['on', 'off'],
'lists': [
[[1, 1, 1], [2, 2, 2], [3, 3, 3]],
[[np.nan], [np.nan], [np.nan]],
'dicts': [
{'S': {'val': 'A'}},
{'S': {'val': np.nan}},
]
})
인 판다를 그대로 합니다.nan
§:
json.dumps(df.to_dict(orient='record'))
> [{
"words": "on",
"lists": [[1, 1, 1], [2, 2, 2], [3, 3, 3]],
"dicts": {"S": {"val": "A"}}
},
{
"words": "off",
"lists": [[NaN], [NaN], [NaN]],
"dicts": {"S": {"val": NaN}}
}]
팬더에게 직접 JSON 문자열로 변환해 달라고 하면 해결됩니다.
df.to_json(orient='records')
> [{
"words": "on",
"lists": [[1,1,1],[2,2,2],[3,3,3]],
"dicts": {"S":{"val":"A"}}
},
{
"words": "off",
"lists": [[null],[null],[null]],
"dicts": {"S":{"val":null}}
}]
에 주의:orient
이 약간 to_dict()
★★★★★★★★★★★★★★★★★」to_json()
.
표준 라이브러리 사용
목록, 딕트 및 스칼라 값만 사용하는 경우 NaN을 수동으로 변환할 수 있습니다.
import math
def to_none(val):
if math.isnan(val):
return None
return val
다음 예제에서는 nan을 None으로 바꿉니다.
>>> import simplejson
>>> a = {"example": float("nan")}
>>> a
{'example': nan}
>>> b = simplejson.dumps(a)
>>> b
'{"example": NaN}'
>>> c = simplejson.loads(b, parse_constant=lambda x: None)
>>> c
{'example': None}
다음의 회피책을 사용합니다.
json_constant_map = {
'-Infinity': float('-Infinity'),
'Infinity': float('Infinity'),
'NaN': None,
}
def json_nan_to_none(obj: typing.Any, *, default: typing.Callable = None) -> None:
# We want to convert NaNs to None and we have to use for now this workaround.
# We still want an exception for infinity and -infinity.
# See: https://github.com/python/cpython/pull/13233
json_string = json.dumps(obj, default=default)
return json.loads(
json_string,
parse_constant=lambda constant: json_constant_map[constant],
)
사전을 문자열로 직렬화한 다음 "NaN"을 "null"로 바꾼 다음 다시 인코딩할 수 있습니다.
d = json.dumps(d) # json dump string
d = d.replace("NaN", "null")
d = json.loads(d) # json load string
하지만 조심해야 해요.어떤 이유로 "NaN"이 사전 내의 어떤 키 또는 값의 문자열의 일부인 경우, 이 경우 교체 단계에서 추가 관리가 필요합니다.
당신은 simplejson을 사용할 수 있지만 만약 당신이 JSON 모듈만 사용하고 싶다면 나의 트릭은
json.dumps(d).replace(", NaN," , ', "null",')
Python json 표준 라이브러리에서 이를 커스터마이즈할 수 있는 PR이 있지만 아직 Marge되지 않았습니다.
과 같습니다.NaN
로로 합니다.None
네스트 리스트도 꽤 잘 처리되는 것 같습니다.dicts의 재귀는 자동으로 처리됩니다.
def null_convert(obj):
if isinstance(obj, dict):
for i in obj:
if isinstance(obj[i], float) and np.isnan(obj[i]):
obj[i]= None
if isinstance(obj[i], list):
for j,v in enumerate(obj[i]):
if isinstance(v, float) and np.isnan(v):
obj[i][j] = None
return obj
json.loads(json_str, object_hook = null_convert)
@secrigo-silveira가 대답한 것처럼 DataFrame을 dict에서 json으로 브릿지로 사용하는 것은 좋은 방법입니다.pd.to_json()을 사용하는 것이 좋습니다.질문 코드의 예에 코드 예를 추가해 보겠습니다.이것이, 이 대답을 참조하는 사람에게 도움이 될 것으로 기대하고 있습니다.
import pandas as pd
from json import dumps, loads
import numpy as np
d = {'a': 1, 'b': 2, 'c': 3, 'e': np.nan, 'f': [1, np.nan, 3]}
df = pd.DataFrame.from_dict(d, orient='index')
json_result = dumps(loads(df.to_json())['0'])
print(json_result)
>>>{"a": 1, "b": 2, "c": 3, "e": null, "f": [1, null, 3]}
팬더를 이용하고 있는데 플라스크를 통해 JSON을 서비스하고 싶습니다. 쓰면 될 것 요..replace
해결할 수 합니다.
from numpy import nan as np_nan
...
@app.route('/json')
def json_endpoint():
df = pd.DataFrame(...)
df = df.replace(to_replace=np_nan, value=None)
return df.to_dict()
@alexander 유감스럽게도 JSON은 지원하지 않습니다.
np.nan, np.NaN, np.inf,
null만 지원합니다.이 매뉴얼을 참조해 주세요.그러나 Python에서는 None 옵션이 있으므로 null 값을 None 키워드로 대체할 수 있습니다.
Python의 데이터 프레임 또는 목록을 JSON으로 변환할 때 발생하는 다른 문제는 numpy datype을 지원하지 않기 때문에 JSON 허용 가능한 데이터 유형으로 변환할 필요가 있다는 것입니다.아래는 같은 해결책입니다.
class CustomJSONizer(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
if isinstance(obj, np.floating):
return float(obj)
if isinstance(obj, np.ndarray):
return obj.tolist()
if isinstance(obj, np.bool_):
return super().encode(bool(obj))
return super(CustomJSONizer, self).default(obj)
이 클래스는 JSON 파일을 사용하는 동안 발생할 수 있는 다양한 데이터 유형을 처리하는 사용자 지정 클래스입니다.이걸 부르려면 json.dumps를 사용해야 합니다.
with open('filename.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(Return_content,cls=CustomJSONizer, ensure_ascii=False))
가장 심플한 솔루션
NaN을 null로 변환하는 재귀 알고리즘
def transform(obj):
"""Function to check the data type to catch NaN and return the null value or return legitimate data type"""
if isinstance(obj, float) and np.isnan(obj):
return None
if isinstance(obj, np.ndarray):
return obj.tolist()
if isinstance(obj, np.integer):
return int(obj)
if isinstance(obj, np.floating):
return float(obj)
return obj
def checking_object(obj):
""" Take the dictionary element and recursively check inside
the nested dictionary containing lists or lists containing Dictionary and converts NaN to null"""
obj = transform(obj)
if isinstance(obj, dict):
for key in obj:
if isinstance(obj[key], list) or isinstance(obj[key], dict):
obj[key] = checking_object(obj[key])
else:
obj[key] = transform(obj[key])
if isinstance(obj, list):
for idx, val in enumerate(obj):
if isinstance(val, list) or isinstance(val, dict):
obj[idx] = checking_object(val)
else:
obj[idx] = transform(val)
return obj
이 가능합니다.NaN
로.null
여기 미국에서checking_object
기능. transformed_object = checking_object(json_having_NaN)
다음과 같은 서드파티 라이브러리를 설치할 필요가 없습니다.simplejson
언급URL : https://stackoverflow.com/questions/28639953/python-json-encoder-convert-nans-to-null-instead
'programing' 카테고리의 다른 글
각진 컴포넌트 기반의 접근방식과 라우터에서의 해결 능력으로 작업 (0) | 2023.03.21 |
---|---|
JSON 문자열을 JsonResult로 변환할 수 있습니까? (0) | 2023.03.21 |
mongoose vs mongodb(nodejs 모듈/확장) 중 어느 쪽이 나을까요?그리고 왜? (0) | 2023.03.21 |
WP 'body' 클래스에 Woocommerce 상위 범주 추가 (0) | 2023.03.21 |
AngularJS 조건부 ng-disabled가 다시 활성화되지 않음 (0) | 2023.03.21 |