【问题标题】:list as an entry in a dict not JSON serializable列表作为字典中的条目不可 JSON 序列化
【发布时间】:2015-12-04 18:10:26
【问题描述】:

我需要将一个列表(或一个 numpy 数组)保存为 JSON 文件中的条目之一。我收到“not JSON-serializable”错误,我不知道如何修复它(以及为什么当我手动将列表传递给字典时我没有得到它)​​。

我的代码:

def get_col_stats(colname, numrows=None):
    print('start reading the column')
    df = pd.read_csv('faults_all_main_dp_1_joined__9-4-15.csv', engine='c', usecols=[colname], nrows = numrows)
    print('finished reading ' + colname)

    df.columns = ['col']
    uniq = list(df.col.unique())
    count = len(uniq)
    print('unique count is', count)

    if colname == 'faultDate':
        return {'type': 'date', 'min': df.col.min(), 'max': df.col.max()}
    elif count < 100000 or colname == 'name':
        return {'type': 'factor', 'uniq': uniq}
    else:
        return {'type': 'numeric', 'min': df.col.min(), 'max': df.col.max()}

d = {}

i = 'faultCode'
d[i] = get_col_stats(i, numrows=1000)
print(d)
print(type(d['faultCode']['uniq']))

json.dumps(d)

输出:

start reading the column
finished reading faultCode
unique count is 114

{'faultCode': {'uniq': [3604, 4179, 2869, ... 57], 'type': 'factor’}}

<class 'list'>

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-84-a877aa1b2642> in <module>()
      7 print(d)
      8 
----> 9 json.dumps(d)

/home/shiny/anaconda3/lib/python3.4/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    228         cls is None and indent is None and separators is None and
    229         default is None and not sort_keys and not kw):
--> 230         return _default_encoder.encode(obj)
    231     if cls is None:
    232         cls = JSONEncoder

/home/shiny/anaconda3/lib/python3.4/json/encoder.py in encode(self, o)
    190         # exceptions aren't as detailed.  The list call should be roughly
    191         # equivalent to the PySequence_Fast that ''.join() would do.
--> 192         chunks = self.iterencode(o, _one_shot=True)
    193         if not isinstance(chunks, (list, tuple)):
    194             chunks = list(chunks)

/home/shiny/anaconda3/lib/python3.4/json/encoder.py in iterencode(self, o, _one_shot)
    248                 self.key_separator, self.item_separator, self.sort_keys,
    249                 self.skipkeys, _one_shot)
--> 250         return _iterencode(o, 0)
    251 
    252 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/home/shiny/anaconda3/lib/python3.4/json/encoder.py in default(self, o)
    171 
    172         """
--> 173         raise TypeError(repr(o) + " is not JSON serializable")
    174 
    175     def encode(self, o):

TypeError: 3604 is not JSON serializable

但是:

d = {}
d['model'] = {'cont': False, 'uniq': [1,2,3,4]}
json.dumps(d)

... 工作正常。

【问题讨论】:

  • 什么是print type(d['faultCode']['uniq'][0])?这是说3604 不可序列化,而不是列表。
  • 它是 。我需要将其转换为浮点/整数吗?

标签: python json list dictionary


【解决方案1】:

好像有一个bug in numpy caused by a lack of flexibility in Python's json module。该错误报告中有一个decent workaround

>>> import numpy, json
>>> def default(o):
...     if isinstance(o, numpy.integer): return int(o)
...     raise TypeError
... 
>>> json.dumps({'value': numpy.int64(42)}, default=default)
'{"value": 42}'

基本上,json.dumps() 接受 default 参数:

default(obj) 是一个应该返回 obj 的可序列化版本或引发 TypeError 的函数。默认只是简单地提高TypeError

发布的解决方法只是将一个函数传递给json.dumps(),将numpy.integer 值转换为int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2013-01-26
    • 2018-07-24
    • 2017-05-17
    • 1970-01-01
    相关资源
    最近更新 更多