Why does json.dumps(list(np.arange(5))) fail while json.dumps(np.arange(5).tolist()) works

前端 未结 3 1557
鱼传尺愫
鱼传尺愫 2020-12-09 03:15

I noticed this problem when a computer running Ubuntu was updated recently and the default version of Python changed to 2.7.

import json
import numpy as np

         


        
相关标签:
3条回答
  • 2020-12-09 03:39

    The problem is that with the first you don't get an int. You get a numpy.int64. That cannot be serialized.

    0 讨论(0)
  • 2020-12-09 04:02

    It looks like the tolist() method turns the numpy int32 (or whatever size you have) back into an int, which JSON knows what to do with:

    >>> 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'>
    

    As the docs say for tolist():

    Return the array as a (possibly nested) list.

    Return a copy of the array data as a (nested) Python list. Data items are converted to the nearest compatible Python type.

    The last line makes the difference here.

    0 讨论(0)
  • 2020-12-09 04:03

    Because the elements of a NumPy array are not native ints, but of NUmPy's own types:

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

    You can use a custom JSONEncoder to support the ndarray type returned by 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))
    
    0 讨论(0)
提交回复
热议问题