我正在用Rust编写一个Python模块,使用的是Py03.在其中一个Rust函数中,我调用了一个python函数my_py_func,该函数返回一个numpy.ndarray,其中包含dtype=int64个条目,对于某些动态确定的k,返回shape=(k,2)个条目.

我的铁 rust 代码是这样的.

let my_py_func_rs = PyModule::import(py, "__main__").unwrap().getattr("my_py_func").unwrap().into();

// input argument to the python function
// my_input_array is a ndarray::Array1<u8>
let args = PyTuple::new(py, &[my_input_array.into_pyarray(py)]);

let output_array: Vec<Vec<usize>> = my_py_func_rs.call1(py, args).unwrap().extract(py).unwrap();

这很管用!按预期进行编译和运行.

但我有一种感觉,使用向量的向量作为数据 struct 是不正确的,也不是最优的.我想对output_array执行的后续操作是遍历各行,并根据每行执行一些操作.我想提取每一点性能,因为最终的代码将运行数天/数周.

Array2会更快吗?我不能测试这一点,因为我不知道如何将python函数输出转换为Array2.我还在代码中的其他地方使用了numpy crate,如果这是相关的.

对于output_array来说,最快的数据 struct 是什么?

推荐答案

我假设您已经将Rust环境设置为使用Py03和NumPy crate .或者更确切地说,在你的Cargo 中.在下面,设置如下.

[dependencies]
numpy = "0.15.0"  # Specify the version you need
pyo3 = "0.15.0"   # Specify the version you need
ndarray = "0.15.0" # Specify the version you need
use numpy::{PyArray2, IntoPyArray};
use pyo3::{Python, PyResult, PyModule, PyTuple};

fn call_python_function(py: Python) -> PyResult<ndarray::Array2<usize>> {
    let my_py_func_rs = PyModule::import(py, "__main__")?.getattr("my_py_func")?.into();

    // Assume my_input_array is a ndarray::Array1<u8>
    let args = PyTuple::new(py, &[my_input_array.into_pyarray(py)]);

    let output_pyarray = my_py_func_rs.call1(py, args)?.extract::<&PyArray2<i64>>(py)?;
    
    // Convert to ndarray::Array2<usize>
    let output_array = output_pyarray.as_array().mapv(|x| x as usize);

    Ok(output_array)
}


look at pyo3 documentation for datastructure for output array here: https://docs.rs/numpy/latest/numpy/array/struct.PyArray.html and
https://docs.rs/numpy/latest/numpy/array/type.PyArray2.html .

当前版本为NumPy="0.20.0"

此外,您还可以

use ndarray::Array2;

// ...

let output_array: Vec<Vec<usize>> = my_py_func_rs.call1(py, args).unwrap().extract(py).unwrap();
let output_array_nd = Array2::from_pyarray(py, output_array);

Rust相关问答推荐

为什么父作用域中的变量超出了子作用域

rust 蚀将动力特性浇到混凝土 struct 上是行不通的

有没有更好的方法从HashMap的条目初始化 struct ?

可以为rust构建脚本编写单元测试吗?

程序在频道RX上挂起

Rust将String上的迭代器转换为&;[&;str]

由于生存期原因,返回引用的闭包未编译

为什么我必须使用 PhantomData?在这种情况下它在做什么?

在使用粗粒度锁访问的数据 struct 中使用 RefCell 是否安全?

Rust: 目标成员属于哪个"目标家族"的列表是否存在?

在不安全的 Rust 中存储对 struct 内部数据的静态引用是否合法?

Rust Redis 中的 HSET 命令问题

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

为什么 Rust 允许写入不可变的 RwLock?

预期的整数,找到 `&{integer}`

字符串切片的向量超出范围但原始字符串仍然存在,为什么判断器说有错误?

在 Rust 中返回对枚举变体的引用是个好主意吗?

如何阅读 HttpRequest 主体