PyO3/rust-numpy

PyO3-based Rust bindings of the NumPy C-API

What it is

rust‑numpy is a Rust library that lets you call NumPy’s C‑API from Rust and also expose Rust functions as Python modules. In practice it bridges the two ecosystems: you can write high‑performance Rust code that works with NumPy arrays, and you can write Python extensions in Rust.

Why it matters

  • Speed & safety – Rust gives you zero‑cost abstractions and memory‑safety guarantees while still being able to manipulate the same ndarray structures that NumPy uses.
  • Seamless interop – No manual pointer gymnastics; the crate provides safe wrappers (PyArray, PyReadonlyArray, etc.) that convert to/from Rust’s ndarray types.
  • Works both ways – You can either:
    1. Write a Python module in Rust (expose #[pyfunction]s that accept/return NumPy arrays), or
    2. Drive Python/NumPy from a Rust binary (embed the interpreter, call np functions, read results).
  • Leverages existing crates – built on top of PyO3 for Python bindings and ndarray for Rust‑side matrix handling.

Core features (as described in the README)

Feature What you get
NumPy C‑API bindings Direct access to NumPy arrays without copying data.
Safe Rust wrappers Types like PyArrayDyn<T>, PyReadonlyArrayDyn<T>, IntoPyArray, and methods for borrowing (as_array, as_array_mut).
Automatic conversion Convert between ndarray::Array* and NumPy arrays via into_pyarray and as_array.
Examples Simple module (axpy, mult) and an example of embedding Python to call np.absolute.
Parallel & linear‑algebra support Example projects show using rayon for parallelism and ndarray‑linalg for BLAS/LAPACK ops.
Version compatibility Supports Rust ≥ 1.85, Python ≥ 3.9, NumPy ≥ 1.16, and a range of ndarray versions (0.15‑0.17).

Who would use it

  • Data‑science / ML developers who want to write performance‑critical kernels in Rust but stay inside the familiar Python/NumPy workflow.
  • Rust developers building Python extensions (e.g., custom NumPy ufuncs, fast preprocessing steps).
  • Researchers needing safe, fast interop between Rust‑based algorithms and existing Python codebases.

Getting started (quick steps)

  1. Add to Cargo.toml:
    [dependencies]
    pyo3 = { version = "0.30", features = ["auto-initialize"] }
    numpy = "0.30"
    
  2. Write a Rust function that uses numpy::{PyArray, PyReadonlyArray, IntoPyArray} and annotate it with #[pyfunction].
  3. Build the crate as a cdylib and import it from Python like any other extension module.
  4. Or, write a regular fn main() that calls Python::with_gil(|py| { … }) to run Python code from Rust.

Limitations / gotchas (from the README)

  • You must have a compatible NumPy installation in the Python environment you target.
  • The crate re‑exports ndarray; if you depend on a different ndarray version you may need to manually unify versions with cargo update.
  • Python 3.7/3.8 support was dropped in recent releases (0.29/0.30).

Community & contribution

  • Issues and pull requests are welcomed on GitHub.
  • The project follows PyO3’s contribution guidelines and has a Gitter channel for discussion.

All information above is taken directly from the repository’s README; no external assumptions have been added.

Related

  • Project
  • Project
  • Project
  • Project