web-dev-qa-db-ja.com

Python JSONエンコーダはNaNを代わりに「null」に変換します

JSONに変換できる任意のオブジェクト(おそらくネストされている)を受け取るコードを書いています。

Pythonの組み込みJSONエンコーダーのデフォルトの動作は、NaNをNaNに変換することです。 json.dumps(np.NaN)NaNを返します。このNaN値を_'null'_に変更するにはどうすればよいですか?

次のように サブクラスJSONEncoderdefault()メソッド をオーバーライドしようとしました:

_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]}'_

27
Alexander

これは私の目的を達成しているようです:

import simplejson


>>> simplejson.dumps(d, ignore_nan=True)
Out[3]: '{"a": 1, "c": 3, "b": 2, "e": null, "f": [1, null, 3]}'
20
Alexander

残念ながら、おそらく@Bramarの提案を使用する必要があります。これを直接使用することはできません。 ドキュメント PythonのJSONエンコーダの状態:

指定されている場合、デフォルトは、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数です

君の NanConverter.defaultメソッドは呼び出されていません。PythonのJSONエンコーダーがすでに知っているためシリアライズ方法np.nan。いくつかの印刷ステートメントを追加します-メソッドが呼び出されていないことがわかります。

7
Gerrat
  1. @Gerratが指摘するように、フックdumps(d, cls=NanConverter)は残念ながら機能しません。

  2. @Alexanderのsimplejson.dumps(d, ignore_nan=True)は機能しますが、追加の依存関係(simplejson)が導入されます。

別の依存関係(パンダ)を導入する場合:

  1. 別の明らかな解決策はdumps(pd.DataFrame(d).fillna(None))ですが、 Pandas issue 1972d.fillna(None)が予測できない動作をすることに注意しています。

    fillna(None)fillna()と同等であることに注意してください。これは、valueパラメータが未使用であることを意味します。代わりに、デフォルトでフォワードフィルであるメソッドパラメータを使用します。

  2. 代わりに、DataFrame.where

    df = pd.DataFrame(d)
    dumps(df.where(pd.notnull(df), None)))
    
6
Michael Currie

pandasを使用している場合:

df = df.replace({pd.np.nan: None})

Githubの問題 で、この人物にクレジットが付与されます。

2
EliadL

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が日時を正しく解析できるようにするです。

1
eiTan LaVi