web-dev-qa-db-ja.com

numpyタイプをpython

パンダから生成した次の形式の辞書のリストがあります。 JSON形式に変換したいです。

list_val = [{1.0: 685}, {2.0: 8}]
output = json.dumps(list_val)

ただし、json.dumpsはエラーをスローします:TypeError:685 is not JSON serializable

Numpyからpython(?)への型変換の問題だと思います。

ただし、np.int32(v)を使用して配列の各辞書の値vを変換すると、エラーがスローされます。

編集:ここに完全なコードがあります

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

あなたは正しいようです:

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

ここでの不幸なことは、numpyの数字の__repr__typeそれらが何であるかについてのヒントを与えないことです。そうでない場合は、intsとしてマスカレードを実行しています(gasp)。最終的に、jsonintがシリアル化可能ではないことを伝えているように見えますが、実際には、この特定のnp.int32(または実際に持っている型)はそうではないことを伝えていますシリアライズ可能。 (そこに本当の驚きはありません-np.int32 isシリアライズ可能です)。これはまた、必然的にbeforejson.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で置き換えますが、... mehです。クラスはより拡張可能です:-)

92
mgilson

配列をpythonリスト(tolistメソッドを使用))に変換してから、リストをjsonに変換することもできます。

4

pandasオブジェクトのいずれかにデータを残した場合、ライブラリはto_json関数は、シリーズ、データフレーム、およびその他すべての高次元のいとこで機能します。

Series.to_json() を参照してください

1
mobiusklein

NumPy int64を処理するには、ujsonのフォークを使用できます。 caiyunapp/ultrajson:Python bindings and NumPy bindings で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]}'
1
ringsaturn