为什么json.dumps(list(np.arange(5)))失败而json.dumps(np.arange(5).tolist())有效

时间:2012-07-19 13:28:36

标签: python numpy python-2.7

当最近更新运行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()方法有区别吗?

3 个答案:

答案 0 :(得分:24)

因为NumPy数组的元素不是本机int,而是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))

答案 1 :(得分: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类型。

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

答案 2 :(得分:1)

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