【问题标题】:Why are some numpy datatypes JSON serializable and others not?为什么某些 numpy 数据类型 JSON 可序列化而其他数据类型不可序列化?
【发布时间】:2017-11-11 13:16:05
【问题描述】:

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

我在我的程序中发现了一个问题,float32s 不是 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() 被用来显示它们的值。 这可能是无意的吗?或者这种行为有充分的理由吗?

【问题讨论】:

  • 您是直接创建np.float32(...) 对象吗?或者它是从数组中提取的?是否尝试序列化 arr.tolist() 等效项?
  • 如果需要序列化数组的元素,可以考虑使用.item()方法将其转换为Python标量。
  • 另见stackoverflow.com/questions/27050108/…Convert numpy type to python

标签: python json numpy serialization types


【解决方案1】:

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 兼容类型不适用。

【讨论】:

  • 那为什么float64float_ 工作? &gt;&gt;&gt; np.float64 is float&gt;&gt;&gt; np.float_ is float 都返回 False
  • 你也可以看看__mro__np.float64.__mro__ 包括 float,np.float32.__mro__` 不包括。
猜你喜欢
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
相关资源
最近更新 更多