Skip to main content

JSON encoder for NumPy arrays and extended Python data types

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

numpy_json-0.1.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

numpy_json-0.1.0-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file numpy_json-0.1.0.tar.gz.

File metadata

  • Download URL: numpy_json-0.1.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for numpy_json-0.1.0.tar.gz
Algorithm Hash digest
SHA256 59f1e5d9247d4796af12fcf7c8e18c2a7bdcc084567d402aa6f71674b0c4d86f
MD5 b7601811277ebbf6f58df020d3a2be13
BLAKE2b-256 bad77103a6e64dce6a37ef04c0439b7c10ed843c526bfb108b7be0c0d34868bd

See more details on using hashes here.

File details

Details for the file numpy_json-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: numpy_json-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for numpy_json-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 598aba0886791eee94ffe125684a09b8ba3e3079e282959100a609089444a31b
MD5 f858b9e5d2998e7d63657f09845eb443
BLAKE2b-256 1d50657ee74d759fd7b050542f4c4c7252304c6fbb07a732991108b5b0a928d8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page