Borislav Hadzhiev
Last updated: Apr 20, 2022
Photo from Unsplash
The Python "TypeError: Object of type int64 is not JSON serializable" occurs
when we try to convert a numpy int64 object to a JSON string. To solve the
error, convert the numpy int to a Python integer before converting it to JSON,
e.g. int(my_numpy_int)
.
Here is an example of how the error occurs.
import json import numpy as np salary = np.power(100, 4, dtype=np.int64) # ⛔️ TypeError: Object of type int64 is not JSON serializable json_str = json.dumps({'salary': salary}) print(json_str)
We tried passing a numpy int64 object to the json.dumps()
method but the
method doesn't handle numpy integers by default.
To solve the error, use the built-in int()
(or float
) constructor to convert
the numpy integer to a native Python integer before serializing it.
import json import numpy as np salary = np.power(100, 4, dtype=np.int64) # 👇️ convert to int json_str = json.dumps({'salary': int(salary)}) print(json_str) # 👉️ '{"salary": 100000000}' print(type(json_str)) # 👉️ <class 'str'>
The default JSON encoder handles int
and float
values, so we can use a
native Python int
instead of a numpy int when serializing to JSON.
The json.dumps method converts a Python object to a JSON formatted string.
Alternatively, you can extend from the JSONEncoder
class and handle the
conversions in a default
method.
import json import numpy as np salary = np.power(100, 4, dtype=np.int64) class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) json_str = json.dumps({'salary': salary}, cls=NpEncoder) print(json_str) # 👉️ '{"salary": 100000000}' print(type(json_str)) # 👉️ <class 'str'>
We extended from the JSONEncoder class.
The JSONEncoder
class supports the following objects and types by default.
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int and float derived Enums | number |
True | true |
False | false |
None | null |
Notice that the JSONEncoder
class doesn't support numpy int64 to JSON
conversion by default.
We can handle this by extending from the class and implementing a default()
method that returns a serializable object.
import json import numpy as np class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj)
If the passed in object is an instance of np.integer
, we convert the object to
a Python int
and return the result.
If the passed in object is an instance of np.floating
, we convert it to a
Python float
and return the result.
If the object is an instance of np.ndarray
, we convert it to a Python list
and return the result.
To use a custom JSONEncoder
, specify it with the cls
keyword argument in
your call to the json.dumps()
method.
import json import numpy as np salary = np.power(100, 4, dtype=np.int64) class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) # ✅ pass cls kwarg json_str = json.dumps({'salary': salary}, cls=NpEncoder) print(json_str) # 👉️ '{"salary": 100000000}' print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.