15 releases (8 breaking)

✓ Uses Rust 2018 edition

0.9.0 May 14, 2020
0.8.0 Mar 19, 2020
0.7.0 Sep 7, 2019
0.6.0 May 26, 2019
0.2.1 May 16, 2017

#84 in FFI

Download history 555/week @ 2020-01-25 668/week @ 2020-02-01 871/week @ 2020-02-08 694/week @ 2020-02-15 637/week @ 2020-02-22 123/week @ 2020-02-29 272/week @ 2020-03-07 299/week @ 2020-03-14 589/week @ 2020-03-21 591/week @ 2020-03-28 410/week @ 2020-04-04 458/week @ 2020-04-11 269/week @ 2020-04-18 271/week @ 2020-04-25 346/week @ 2020-05-02 484/week @ 2020-05-09

1,776 downloads per month
Used in 4 crates

Custom license

125KB
2K SLoC

Ruby HTML 2K SLoC // 0.2% comments Scons 40 SLoC // 0.2% comments

rust-numpy

Build Status Build status Crate

Rust bindings for the NumPy C-API

API documentation

Requirements

Note Starting from 0.3, rust-numpy migrated from rust-cpython to pyo3. If you want to use rust-cpython, use version 0.2.1 from crates.io.

Supported Python version

Currently 3.5, 3.6, 3.7, and 3.8 are supported.

Python2 Support

Version 0.5.0 is the last version that supports Python2.

If you want to compile this library with Python2, please use 0.5.0 from crates.io.

In addition, you have to add a feature flag in Cargo.toml like

[dependencies.numpy]
version = "0.5.0"
features = ["python2"]

.

You can also automatically specify python version in setup.py, using setuptools-rust.

Example

Execute a Python program from Rust and get results

[package]
name = "numpy-test"

[dependencies]
pyo3 = "0.10.1"
numpy = "0.9.0"
use numpy::{PyArray1, get_array_module};
use pyo3::prelude::{PyResult, Python};
use pyo3::types::PyDict;

fn main() -> Result<(), ()> {
    let gil = Python::acquire_gil();
    main_(gil.python()).map_err(|e| {
        eprintln!("error! :{:?}", e);
        // we can't display python error type via ::std::fmt::Display
        // so print error here manually
        e.print_and_set_sys_last_vars(gil.python());
    })
}

fn main_<'py>(py: Python<'py>) -> PyResult<()> {
    let np = py.import("numpy")?;
    let dict = PyDict::new(py);
    dict.set_item("np", np)?;
    let pyarray: &PyArray1<i32> = py
        .eval("np.absolute(np.array([-1, -2, -3], dtype='int32'))", Some(&dict), None)?
        .extract()?;
    let slice = pyarray.as_slice()?;
    assert_eq!(slice, &[1, 2, 3]);
    Ok(())
}

Write a Python module in Rust

Please see the examples directory for a complete example

[lib]
name = "rust_ext"
crate-type = ["cdylib"]

[dependencies]
numpy = "0.9.0"
ndarray = "0.13"

[dependencies.pyo3]
version = "0.9.0-alpha.1"
features = ["extension-module"]
use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
use numpy::{IntoPyArray, PyArrayDyn};
use pyo3::prelude::{pymodule, Py, PyModule, PyResult, Python};

#[pymodule]
fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> {
    // immutable example
    fn axpy(a: f64, x: ArrayViewD<f64>, y: ArrayViewD<f64>) -> ArrayD<f64> {
        a * &x + &y
    }

    // mutable example (no return)
    fn mult(a: f64, mut x: ArrayViewMutD<f64>) {
        x *= a;
    }

    // wrapper of `axpy`
    #[pyfn(m, "axpy")]
    fn axpy_py(
        py: Python,
        a: f64,
        x: &PyArrayDyn<f64>,
        y: &PyArrayDyn<f64>,
    ) -> Py<PyArrayDyn<f64>> {
        let x = x.as_array();
        let y = y.as_array();
        axpy(a, x, y).into_pyarray(py).to_owned()
    }

    // wrapper of `mult`
    #[pyfn(m, "mult")]
    fn mult_py(_py: Python, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
        let x = x.as_array_mut();
        mult(a, x);
        Ok(())
    }

    Ok(())
}

Contribution

We need your feedback.

Don't hesitate to open issues!

Dependencies

~2.5MB
~48K SLoC