NumPy
JSON
Serialization
Python
Data Handling

NumPy array is not JSON serializable

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The error NumPy array is not JSON serializable happens because Python's built-in json module knows how to encode native Python types such as lists, dicts, strings, and numbers, but not numpy.ndarray objects. The fix is usually to convert NumPy values into plain Python data structures before calling json.dumps.

Why the Error Happens

A NumPy array is a specialized object with metadata about shape, dtype, and memory layout. JSON has no concept of that object model. It can only represent simple data structures.

So this fails:

python
1import json
2import numpy as np
3
4arr = np.array([1, 2, 3])
5print(json.dumps(arr))

The json module does not know how to turn ndarray into a valid JSON structure automatically.

The Usual Fix: Convert to a List

For many applications, the direct solution is tolist().

python
1import json
2import numpy as np
3
4arr = np.array([1, 2, 3])
5json_text = json.dumps(arr.tolist())
6print(json_text)

For multidimensional arrays, tolist() returns nested Python lists, which serialize cleanly.

python
matrix = np.array([[1, 2], [3, 4]])
print(json.dumps(matrix.tolist()))

This is the simplest and most common answer when you just need the numeric content in JSON form.

Handle NumPy Scalars Too

NumPy scalar types can trigger similar issues.

python
1import json
2import numpy as np
3
4value = np.int64(42)
5print(json.dumps(int(value)))

Common conversions are:

  • 'int(np.int64_value)'
  • 'float(np.float32_value)'
  • 'bool(np.bool_value)'

If your structure contains both arrays and scalar dtypes, you need to convert both kinds.

Use a Custom Encoder for Repeated Use

If NumPy values appear throughout a larger data structure, a custom JSON encoder can keep the call sites cleaner.

python
1import json
2import numpy as np
3
4class NumpyEncoder(json.JSONEncoder):
5    def default(self, obj):
6        if isinstance(obj, np.ndarray):
7            return obj.tolist()
8        if isinstance(obj, np.integer):
9            return int(obj)
10        if isinstance(obj, np.floating):
11            return float(obj)
12        if isinstance(obj, np.bool_):
13            return bool(obj)
14        return super().default(obj)
15
16payload = {
17    "values": np.array([1, 2, 3]),
18    "count": np.int64(3)
19}
20
21print(json.dumps(payload, cls=NumpyEncoder))

This is a good pattern when the project serializes NumPy-heavy payloads in multiple places.

Preserve Shape or Metadata Explicitly

If the consumer needs more than the raw values, include metadata yourself rather than assuming JSON will carry it implicitly.

python
1import json
2import numpy as np
3
4arr = np.array([[1, 2], [3, 4]], dtype=np.int32)
5
6payload = {
7    "data": arr.tolist(),
8    "shape": list(arr.shape),
9    "dtype": str(arr.dtype),
10}
11
12print(json.dumps(payload))

That approach is useful when the receiver needs to reconstruct the array with the expected dimensions or numeric type.

Remember What JSON Loses

JSON can store the numbers, but it does not preserve NumPy dtype semantics or array shape metadata unless you add that information yourself. If exact dtype restoration matters, a richer format such as .npy, Parquet, Arrow, or a custom structured payload may be more appropriate.

For example, if downstream code must know whether values were float32 or float64, raw JSON arrays are usually not enough on their own.

Common Pitfalls

  • Passing an ndarray directly to json.dumps raises the serialization error because json only handles native Python types. Convert first.
  • Converting arrays but forgetting NumPy scalar types can leave the same error elsewhere in the payload. Handle both arrays and scalar dtypes.
  • Assuming JSON preserves dtype and array metadata can lead to incorrect deserialization later. JSON stores values, not NumPy semantics.
  • Using str(arr) to bypass the error produces a string representation, not a structured JSON array. That is usually the wrong format for consumers.
  • Choosing JSON for large numeric data just because it is familiar can be inefficient. Consider array-native formats when precision, size, or speed matters.

Summary

  • 'numpy.ndarray is not directly supported by Python's json encoder.'
  • The usual fix is arr.tolist() before serialization.
  • NumPy scalar types also need conversion to native Python numbers or booleans.
  • A custom JSONEncoder is useful when NumPy values appear across many payloads.
  • JSON is convenient for interchange, but it does not preserve NumPy-specific metadata automatically.

Course illustration
Course illustration

All Rights Reserved.