如何用NDArray输入和PyO3输出包装函数



我想包装一个函数,该函数以一维NDArray(rust-numpy(和usize为参数,并使用PyO3返回一维数组来调用python中的代码。不幸的是,我找不到一个如何在PyO3中处理数组的好例子。这是我目前拥有的代码:

use numpy::ndarray::prelude::*;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
#[pyfunction]
fn sma(prices: &Array1<f32>, period: usize) -> PyResult<Array1<f32>> {
let length = prices.len() - period +1;
let mut result = Array1::<f32>::zeros(length);
for i in 0..length {
let slice = prices.slice(s![i..i+period]);
result[i] = slice.sum()/(period as f32);
}
Ok(result)
}
#[pymodule]
fn panther(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sma, m)?)?;
Ok(())
}

我添加了装饰器和模块包装函数。现在我得到这个错误:

error[E0277]: the trait bound `Result<ArrayBase<OwnedRepr<f32>, Dim<[usize; 1]>>, PyErr>: IntoPyCallbackOutput<_>` is not satisfied.

这是我的车。toml:

[package]
name = "panther"
version = "0.1.0"
edition = "2021"
[lib]
name = "panther"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.12.3", features = ["extension-module"] }
numpy = "0.15"

有人能告诉我如何实际修改SMA功能以用于PyO3吗?非常感谢。

所以我最终弄明白了:

#[pyfunction]
fn sma(a: Vec<f32>, period: usize) -> PyResult<Vec<f32>> {
let prices = Array::from_vec(a);
let length = prices.len() - period +1;
let mut result = Array1::<f32>::zeros(length);
for i in 0..length {
let slice = prices.slice(s![i..i+period]);
result[i] = slice.sum()/(period as f32);
}
Ok(Array::to_vec(&result))
}

问题是PyO3需要定义NDArray,以便将其包装为python。由于我没有这么做,所以我使用了一个Vec,相当于一个浮动列表的python。然后我使用Array::from_vec()将其转换为NDArray。这允许我们从Python列表中获取值,并将其转换为NDArray,以便在Rust中使用NumPy函数进行处理。然后使用Array::to_vec()函数将该列表转换回普通列表,并将其作为普通列表发送回Python。

最新更新