JSONに変換できる任意のオブジェクト(おそらくネストされている)を受け取るコードを書いています。
Pythonの組み込みJSONエンコーダーのデフォルトの動作は、NaNをNaN
に変換することです。 json.dumps(np.NaN)
はNaN
を返します。このNaN
値を_'null'
_に変更するにはどうすればよいですか?
次のように サブクラスJSONEncoder
とdefault()
メソッド をオーバーライドしようとしました:
_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]}'
残念ながら、おそらく@Bramarの提案を使用する必要があります。これを直接使用することはできません。 ドキュメント PythonのJSONエンコーダの状態:
指定されている場合、デフォルトは、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数です
君の NanConverter.default
メソッドは呼び出されていません。PythonのJSONエンコーダーがすでに知っているためシリアライズ方法np.nan
。いくつかの印刷ステートメントを追加します-メソッドが呼び出されていないことがわかります。
@Gerratが指摘するように、フックdumps(d, cls=NanConverter)
は残念ながら機能しません。
@Alexanderのsimplejson.dumps(d, ignore_nan=True)
は機能しますが、追加の依存関係(simplejson
)が導入されます。
別の依存関係(パンダ)を導入する場合:
別の明らかな解決策はdumps(pd.DataFrame(d).fillna(None))
ですが、 Pandas issue 1972 はd.fillna(None)
が予測できない動作をすることに注意しています。
fillna(None)
はfillna()
と同等であることに注意してください。これは、valueパラメータが未使用であることを意味します。代わりに、デフォルトでフォワードフィルであるメソッドパラメータを使用します。
代わりに、DataFrame.where
:
df = pd.DataFrame(d)
dumps(df.where(pd.notnull(df), None)))
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-> null変換を正しく処理します
デフォルトのフラグはsimplejsonが日時を正しく解析できるようにするです。