Skip to main content

numpy-json

License: MIT Python 3.8+

A robust JSON encoder for NumPy arrays and extended Python data types. No more writing custom serialization wrappers — just drop in NumpyJSONEncoder and go.

Features

numpy-json seamlessly handles:

  • NumPy arrays → JSON lists
  • NumPy scalars (int, float, bool) → native JSON types
  • NumPy datetime64/timedelta64 → ISO 8601 strings
  • Python datetime/date/time → ISO 8601 strings
  • UUID → string representation
  • Decimal → float (default) or string (configurable)
  • set/tuple → JSON lists
  • bytes/bytearray → base64 encoded strings (configurable)
  • pathlib.Path → string paths
  • pandas types (optional, no hard dependency) → appropriate JSON types

Installation

pip install numpy-json

Or install from source:

git clone https://github.com/featrix/numpy-json.git
cd numpy-json
pip install -e .

Quick Start

import json
import numpy as np
from numpy_json import NumpyJSONEncoder

# Your data with NumPy arrays
data = {
    "array": np.array([1, 2, 3, 4, 5]),
    "matrix": np.array([[1, 2], [3, 4]]),
    "scalar": np.float64(3.14159),
    "date": np.datetime64('2025-01-15'),
}

# Encode to JSON - it just works!
json_str = json.dumps(data, cls=NumpyJSONEncoder)
print(json_str)

Output:

{
  "array": [1, 2, 3, 4, 5],
  "matrix": [[1, 2], [3, 4]],
  "scalar": 3.14159,
  "date": "2025-01-15"
}

Usage

Basic Usage

Simply pass NumpyJSONEncoder as the cls parameter to json.dumps():

import json
from numpy_json import NumpyJSONEncoder

json_str = json.dumps(your_data, cls=NumpyJSONEncoder)

Configuration Options

The encoder provides class-level configuration:

Decimal Handling

from numpy_json import NumpyJSONEncoder
import decimal

# Default: convert Decimal to float (lossy for very precise decimals)
data = {"price": decimal.Decimal("19.99")}
json.dumps(data, cls=NumpyJSONEncoder)  # → {"price": 19.99}

# Alternative: preserve as string
NumpyJSONEncoder.DECIMAL_AS_STR = True
json.dumps(data, cls=NumpyJSONEncoder)  # → {"price": "19.99"}

Binary Data Handling

from numpy_json import NumpyJSONEncoder

data = {"binary": b"hello world"}

# Default: base64 encoding
json.dumps(data, cls=NumpyJSONEncoder)  
# → {"binary": "aGVsbG8gd29ybGQ="}

# Alternative: emit as integer list
NumpyJSONEncoder.BASE64_BYTES = False
json.dumps(data, cls=NumpyJSONEncoder)
# → {"binary": [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]}

Handling NaN and Infinity

By default, Python's json module allows NaN and Infinity values (which are not valid in RFC 8259 JSON). If you need strict JSON compliance:

import json
import numpy as np
from numpy_json import NumpyJSONEncoder, sanitize_nans

data = {
    "valid": np.array([1.0, 2.0, 3.0]),
    "invalid": np.array([1.0, np.nan, np.inf, -np.inf]),
}

# Clean the data first
clean_data = sanitize_nans(data)
# NaN/Inf values are replaced with None

# Then encode with allow_nan=False for strict JSON
json_str = json.dumps(clean_data, cls=NumpyJSONEncoder, allow_nan=False)

Result:

{
  "valid": [1.0, 2.0, 3.0],
  "invalid": [1.0, null, null, null]
}

Advanced Example

import json
import numpy as np
from datetime import datetime
from uuid import uuid4
from pathlib import Path
from numpy_json import NumpyJSONEncoder

complex_data = {
    "id": uuid4(),
    "timestamp": datetime.now(),
    "measurements": np.array([1.5, 2.3, 3.7, 4.1]),
    "matrix": np.random.rand(3, 3),
    "metadata": {
        "path": Path("/tmp/data.csv"),
        "tags": {"ml", "experiment", "2025"},
        "coordinates": (40.7128, -74.0060),
    },
    "config": {
        "enabled": np.bool_(True),
        "threshold": np.float32(0.85),
        "max_items": np.int64(1000),
    }
}

json_str = json.dumps(complex_data, cls=NumpyJSONEncoder, indent=2)
print(json_str)

API Reference

NumpyJSONEncoder

Class Attributes:

  • DECIMAL_AS_STR (bool): If True, encode Decimal as string. Default: False
  • BASE64_BYTES (bool): If True, encode bytes as base64. Default: True

Methods:

  • default(obj): Override method that handles type conversion

sanitize_nans(obj)

Recursively replace NaN, Inf, and -Inf values with None.

Parameters:

  • obj: Any Python object (dict, list, NumPy array, etc.)

Returns:

  • Object with all NaN/Inf values replaced with None

Type Conversion Table

Python/NumPy Type JSON Output Notes
np.ndarray Array Recursive conversion via .tolist()
np.int* Number All NumPy integer types
np.float* Number All NumPy float types
np.bool_ Boolean NumPy boolean
np.datetime64 String ISO 8601 format
np.timedelta64 String Duration string
datetime/date/time String ISO 8601 format
uuid.UUID String Standard UUID string
decimal.Decimal Number or String Configurable via DECIMAL_AS_STR
set/tuple Array Converted to list
bytes/bytearray String or Array Configurable via BASE64_BYTES
pathlib.Path String String representation
pandas types String or null Optional support, no hard dependency

Requirements

  • Python 3.8+
  • NumPy

Development

Setup

git clone https://github.com/featrix/numpy-json.git
cd numpy-json
pip install -e ".[dev]"

Running Tests

pytest tests/

Code Style

This project uses:

  • black for code formatting
  • flake8 for linting
  • mypy for type checking
black numpy_json/
flake8 numpy_json/
mypy numpy_json/

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright

Copyright (c) 2025 Featrix, Inc.

Acknowledgments

  • Built to solve real-world data serialization challenges in scientific computing and machine learning workflows
  • Inspired by the need for seamless NumPy integration with JSON APIs

Support

For issues, questions, or contributions, please visit the GitHub repository.

Release files for numpy-json 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for numpy-json 0.1.0
File Size Uploaded
numpy_json-0.1.0.tar.gz 7.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for numpy-json 0.1.0
File Interpreter ABI Platform
numpy_json-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.9 kB

Release files / numpy_json-0.1.0.tar.gz

Download URL numpy_json-0.1.0.tar.gz
Size 7.9 kB
Tags Source
SHA-256 checksum
How to use checksums
59f1e5d9247d4796af12fcf7c8e18c2a7bdcc084567d402aa6f71674b0c4d86f
BLAKE2b-256 checksum
How to use checksums
bad77103a6e64dce6a37ef04c0439b7c10ed843c526bfb108b7be0c0d34868bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.4

Release files / numpy_json-0.1.0-py3-none-any.whl

Download URL numpy_json-0.1.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
598aba0886791eee94ffe125684a09b8ba3e3079e282959100a609089444a31b
BLAKE2b-256 checksum
How to use checksums
1d50657ee74d759fd7b050542f4c4c7252304c6fbb07a732991108b5b0a928d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.4

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page