numpy-json
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): IfTrue, encodeDecimalas string. Default:FalseBASE64_BYTES(bool): IfTrue, 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:
blackfor code formattingflake8for lintingmypyfor type checking
black numpy_json/
flake8 numpy_json/
mypy numpy_json/
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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.
Metadata
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)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| numpy_json-0.1.0.tar.gz | 7.9 kB | Without provenance | Details for numpy_json-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| numpy_json-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for numpy_json-0.1.0-py3-none-any.whl |
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
|
Security for numpy-json 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.