为什么一些numpy数据类型JSON可序列化而其他不是?

时间:2017-06-09 13:32:28

标签: python json numpy serialization types

Numpy有很多不同的基本类型,所有这些类型都是listed here

我在我的程序中追踪到float32不是JSON可序列化的问题,所以我开始测试上面列表中的所有数据类型:

>>> import numpy as np
>>> from json import dumps
>>> dumps(np.bool(True))
'true'
>>> dumps(np.bool_(True))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.4/json/encoder.py", line 192, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.4/json/encoder.py", line 250, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.4/json/encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: True is not JSON serializable
>>> dumps(np.int(0))
'0'
>>> dumps(np.int_(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.intc(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.intp(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.int8(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.int16(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.int32(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.int64(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.uint8(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.uint16(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.uint32(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.uint64(0))
Traceback (most recent call last):
  [...]
TypeError: 0 is not JSON serializable
>>> dumps(np.float(0))
'0.0'
>>> dumps(np.float_(0))
'0.0'
>>> dumps(np.float16(0))
Traceback (most recent call last):
  [...]
TypeError: 0.0 is not JSON serializable
>>> dumps(np.float32(0))
Traceback (most recent call last):
  [...]
TypeError: 0.0 is not JSON serializable
>>> dumps(np.float64(0))
'0.0'
>>> dumps(np.complex(0))
Traceback (most recent call last):
  [...]
TypeError: 0j is not JSON serializable
>>> dumps(np.complex_(0))
Traceback (most recent call last):
  [...]
TypeError: 0j is not JSON serializable
>>> dumps(np.complex64(0))
Traceback (most recent call last):
  [...]
TypeError: 0j is not JSON serializable
>>> dumps(np.complex128(0))
Traceback (most recent call last):
  [...]
TypeError: 0j is not JSON serializable

因此,没有complex类型是可序列化的,这是有道理的。

bool有效,bool_没有。 int有效,但其名称中包含int的任何内容都不起作用。 floatfloat_float64都很好,但float16float32不是。

为什么会出现这种情况?显然,它们都可以轻松转换为字符串,堆栈跟踪甚至会显示repr()用于显示其值。 这可能是无心的吗?或者这种行为有充分理由吗?

1 个答案:

答案 0 :(得分:6)

JSON可序列化的数据类型都是Python内置函数:

>>> np.int is int
True
>>> np.float is float
True
>>> np.bool is bool
True

因此,您显示的所有NumPy数据类型都不是JSON可序列化的。至少是一致的。

np.float _与np.float64相同(在MacOS上测试):

>>> np.float_ is np.float64
True

帮助说:

np.float64

  

64位浮点数。字符代码'd'。 Python浮动   兼容。

鉴于:

np.float32

  

32位浮点数。字符代码'f'。 C浮动兼容。

因此,Python浮点兼容类型适用于json.dumps(),但C兼容类型不适用。