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
The problem is that with the first you don't get an int. You get a numpy.int64. That cannot be serialized.
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.
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))