Skip to content

How to Resolve "TypeError: Object of type numpy.int64/float32 is not JSON serializable" in Python

Fix the JSON serialization error when working with NumPy's int64/float32 types by converting them to Python primitives or using custom encoders for seamless data conversion.

When working with NumPy arrays, you might encounter TypeError: Object of type int64 is not JSON serializable or TypeError: Object of type float32 is not JSON serializable. These errors occur because Python's standard json module doesn't natively recognize NumPy's specific numeric types.

This guide explains why this happens and provides several practical solutions for successful JSON serialization.

Understanding the Error: JSON and NumPy Types

JSON (JavaScript Object Notation) is a text-based format with a limited set of data types (strings, numbers, booleans, arrays, objects, null). Python's json.dumps() function can serialize standard Python types like int, float, str, list, dict, bool, and None.

However, NumPy introduces its own, more specialized numeric types (like numpy.int64, numpy.float32) to handle large datasets and optimize performance. These NumPy-specific types are not directly recognized by the default JSON encoder.

import json
import numpy as np

salary_int = np.int64(100000000)

salary_float = np.float32(316227.78)

The simplest and often most effective solution is to explicitly convert the NumPy numeric types to their standard Python equivalents (int or float) before serialization:

Converting NumPy Integers (np.int64, np.int32, etc.)

Use the built-in int() constructor:

import json
import numpy as np

salary_int = np.int64(100000000)

json_str = json.dumps({'salary': int(salary_int)})
print(json_str)         # Output: {"salary": 100000000}
print(type(json_str))   # Output: <class 'str'>

Converting NumPy Floats (np.float32, np.float64, etc.)

Use the built-in float() constructor:

import json
import numpy as np

salary_float = np.float32(316227.78)

json_str = json.dumps({'salary': float(salary_float)})
print(json_str)         # Output: {"salary": 316227.78125}
print(type(json_str))   # Output: <class 'str'>

Solution 2: Create a Custom NumPy JSON Encoder

For situations where you frequently serialize data containing various NumPy types, creating a custom JSONEncoder subclass is a clean and reusable approach:

import json
import numpy as np

class NpEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)             # Convert NumPy int to Python int
        elif isinstance(obj, np.floating):
            return float(obj)           # Convert NumPy float to Python float
        elif isinstance(obj, np.ndarray):
            return obj.tolist()         # Convert NumPy array to Python list
        return super().default(obj)     # Let the base class handle the rest

data_to_serialize = {
    'count': np.int32(5),
    'average': np.float64(12.345),
    'values': np.array([1, 2, 3])
}

json_str = json.dumps(data_to_serialize, cls=NpEncoder)
print(json_str)
  • This custom encoder handles common NumPy integers, floats, and arrays.
  • You pass the custom encoder class to the cls argument of json.dumps().

Solution 3: Use the default Argument in json.dumps()

A simpler alternative to a full class is providing a function to the default argument of json.dumps(). This function handles types the standard encoder doesn't recognize:

import json
import numpy as np

def numpy_serializer(obj):
    if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
                        np.int16, np.int32, np.int64, np.uint8,
                        np.uint16, np.uint32, np.uint64)):
        return int(obj)
    elif isinstance(obj, (np.float_, np.float16, np.float32, np.float64)):
        return float(obj)
    elif isinstance(obj, np.ndarray):
        return obj.tolist()
    raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")

data_to_serialize = {
    'count': np.int32(5),
    'average': np.float64(12.345),
}

json_str = json.dumps(data_to_serialize, default=numpy_serializer)
print(json_str) # Output: {"count": 5, "average": 12.345}
  • The numpy_serializer function checks the type and performs the necessary conversion.
  • Explicitly raising a TypeError for unhandled types in the default function is good practice.

Conclusion

The TypeError related to NumPy int64 or float32 not being JSON serializable stems from the standard json module's inability to handle these specific numeric types.

The most straightforward solution is to explicitly convert NumPy numbers to standard Python int or float types before serialization.

For more complex or frequent scenarios, creating a custom JSONEncoder or using the default argument provides reusable and cleaner ways to handle various NumPy types during JSON conversion.

Navigation