Last updated: Apr 8, 2024
Reading time·5 min
The Python "TypeError: Object of type ndarray is not JSON serializable" occurs when we try to convert a NumPy ndarray object to a JSON string.
To solve the error, use the tolist()
method on the array to convert it to a
Python list before serializing it to JSON.
Here is an example of how the error occurs.
import json import numpy as np arr = np.array([1, 2, 3, 4]) # ⛔️ TypeError: Object of type ndarray is not JSON serializable json_str = json.dumps({'nums': arr})
We tried passing a NumPy ndarray
object to the json.dumps()
method but the
method doesn't handle NumPy arrays by default.
To solve the error, use the tolist()
method on the array to convert it to a
Python list.
import json import numpy as np arr = np.array([1, 2, 3, 4]) # ✅ used tolist() json_str = json.dumps({'nums': arr.tolist()}) print(json_str) # 👉️ {"nums": [1, 2, 3, 4]} print(type(json_str)) # 👉️ <class 'str'>
We can use a native Python list
instead of a NumPy ndarray
when serializing
to JSON.
The json.dumps() method converts a Python object to a JSON formatted string.
If you need to convert the JSON string back to a NumPy array, use the
json.loads()
method.
import json import numpy as np arr = np.array([1, 2, 3, 4]) # ✅ used tolist() json_str = json.dumps({'nums': arr.tolist()}) my_dict = json.loads(json_str) new_arr = np.array(my_dict['nums']) print(new_arr) # 👉️ [1 2 3 4]
The json.loads() method parses a JSON string into a native Python object.
We accessed the Python list and used the np.array
method to convert it to a
NumPy array.
JSONEncoder
class to solve the errorAlternatively, you can extend from the JSONEncoder
class and handle the
conversions in a default
method.
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) arr = np.array([1, 2, 3, 4]) json_str = json.dumps({'nums': arr}, cls=NpEncoder) print(json_str) # 👉️ {"nums": [1, 2, 3, 4]} 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 ndarray
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 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) arr = np.array([1, 2, 3, 4]) # ✅ provide cls keyword argument json_str = json.dumps({'nums': arr}, cls=NpEncoder) print(json_str) # 👉️ {"nums": [1, 2, 3, 4]} print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.
default
keyword argument to solve the errorYou can also use the default
keyword argument in the call to the
json.dumps()
method.
import json import numpy as np arr = np.array([1, 2, 3, 4]) def json_serializer(obj): if isinstance(obj, np.ndarray): return obj.tolist() return obj json_str = json.dumps({'nums': arr}, default=json_serializer) print(json_str) # 👉️ {"nums": [1, 2, 3, 4]}
The json.dumps() method converts a Python object to a JSON formatted string.
default
keyword argument can be set to a function that gets called for objects that can't otherwise be serialized.We simply convert the ndarray
object to a list by using the tolist()
method.
The json_serializer
function takes an object as a parameter and checks if the
object is a ndarray
.
If the condition is met, we use the tolist()
method to convert the array to a
list, otherwise, the value is returned as is.
pandas
to solve the errorIf you use the pandas
module, you can also use the to_json
method to solve
the error.
import numpy as np import pandas as pd arr = np.array([1, 2, 3, 4]) json_str = pd.Series(arr).to_json(orient='values') print(json_str) # 👉️ [1,2,3,4]
The Series.to_json method converts the object to a JSON string.
The orient
argument determines the expected JSON string format.
The values
option is used to only use the array's values in the JSON string.
The Python "TypeError: Object of type DataFrame is not JSON serializable"
occurs when we try to serialize a DataFrame
object to JSON using the
json.dumps
method.
To solve the error, use the to_json()
method instead, e.g. df.to_json()
.
Here is an example of how the error occurs
import json import pandas as pd df = pd.DataFrame( { "Name": [ "Alice", "Bob", "Carl", ], "Age": [29, 30, 31], } ) # ⛔️ TypeError: Object of type DataFrame is not JSON serializable print(json.dumps(df))
We tried passing a DataFrame
object to the json.dumps()
method but the
method doesn't handle DataFrame
objects by default.
to_json()
method to solve the errorTo solve the error, use the to_json()
method on the DataFrame
object.
import pandas as pd df = pd.DataFrame( { "Name": [ "Alice", "Bob", "Carl", ], "Age": [29, 30, 31], } ) # 👇️ '{"Name":{"0":"Alice","1":"Bob","2":"Carl"},"Age":{"0":29,"1":30,"2":31}}' print(df.to_json()) # 👇️ <class 'str'> print(type(df.to_json()))
The to_json()
method converts the DataFrame
object to a JSON string.
DataFrame
to a dict
to solve the errorAlternatively, you can try to convert the DataFrame
to a dict
object before
serializing to JSON.
import json import pandas as pd df = pd.DataFrame( { "Name": [ "Alice", "Bob", "Carl", ], "Age": [29, 30, 31], } ) # 👇️ '{"Name": {"0": "Alice", "1": "Bob", "2": "Carl"}, "Age": {"0": 29, "1": 30, "2": 31}}' print(json.dumps(df.to_dict())) # 👇️ <class 'str'> print(type(json.dumps(df.to_dict())))
The to_dict
method converts the DataFrame
to a dictionary, which we can then
serialize to JSON.
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 |