26

当最近更新运行 Ubuntu 的计算机并且 Python 的默认版本更改为 2.7 时,我注意到了这个问题。

import json
import numpy as np

json.dumps(list(np.arange(5))) # Fails, throws a "TypeError: 0 is not JSON serializable"
json.dumps(np.arange(5).tolist()) # Works 

list() 和 numpy 数组的 tolist() 方法之间有区别吗?

4

3 回答 3

23

因为 NumPy 数组的元素不是原生整数,而是 NumPy 自己的类型:

>>> type(np.arange(5)[0])
<type 'numpy.int64'>

您可以使用自定义JSONEncoder来支持ndarray返回的类型arange

import numpy as np
import json

class NumPyArangeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.ndarray):
            return obj.tolist() # or map(int, obj)
        return json.JSONEncoder.default(self, obj)

print(json.dumps(np.arange(5), cls=NumPyArangeEncoder))
于 2012-07-19T13:31:36.933 回答
23

看起来该tolist()方法将 numpy int32(或您拥有的任何大小)重新转换为int,JSON知道如何处理:

>>> list(np.arange(5))
[0, 1, 2, 3, 4]
>>> type(list(np.arange(5)))
<type 'list'>
>>> type(list(np.arange(5))[0])
<type 'numpy.int32'>
>>> np.arange(5).tolist()
[0, 1, 2, 3, 4]
>>> type(np.arange(5).tolist())
<type 'list'>
>>> type(np.arange(5).tolist()[0])
<type 'int'>

正如文档所说tolist()

将数组作为(可能是嵌套的)列表返回。

将数组数据的副本作为(嵌套)Python 列表返回。数据项被转换为最接近的兼容 Python 类型。

最后一行在这里有所不同。

于 2012-07-19T13:31:37.330 回答
1

问题是第一个你没有得到一个int。你得到一个 numpy.int64。那是不能序列化的。

于 2012-07-19T13:31:58.860 回答