如何解决Rust Polars DataFrame转Python对象的类型不匹配问题?
解决Polars DataFrame与pyo3-polars类型不匹配问题
问题原因
你遇到的类型不匹配错误,本质是依赖版本不兼容:
- 你使用的
polars版本是0.43,但pyo3-polars0.18依赖的是更低版本的Polars(通常为0.41.x系列)。 - 不同版本的Polars中,
DataFrame的导出路径或内部定义发生了变化,导致polars::prelude::DataFrame和pyo3-polars期望的polars_core::frame::DataFrame被编译器判定为完全不同的类型。
解决方案
有两种可行的修复方式,任选其一即可:
方案1:对齐Polars与pyo3-polars的版本
将polars版本降级到pyo3-polars 0.18支持的版本(经确认,pyo3-polars 0.18适配Polars 0.41.x),修改Cargo.toml:
[dependencies] ordered-float = "4.4" polars = { version = "0.41", features = ["lazy", "parquet", "dtype-struct", "dtype-u8", "round_series"] } itertools = "0.13" chrono = "0.4" pyo3 = { version = "0.21", features = ["extension-module"] } pyo3-polars = "0.18"
方案2:升级pyo3-polars以适配Polars 0.43
如果你想保留Polars 0.43,需要升级pyo3-polars到支持该版本的兼容版(pyo3-polars 0.20及以上版本适配Polars 0.43),修改Cargo.toml:
[dependencies] ordered-float = "4.4" polars = { version = "0.43", features = ["lazy", "parquet", "dtype-struct", "dtype-u8", "round_series"] } itertools = "0.13" chrono = "0.4" pyo3 = { version = "0.21", features = ["extension-module"] } pyo3-polars = "0.20"
代码修正(版本对齐后)
版本匹配后,polars::prelude::DataFrame会自动和pyo3-polars期望的类型兼容,同时可以优化to_python函数的写法:
use pyo3::prelude::*; use polars::prelude::*; use pyo3_polars::PyDataFrame; fn get_df() -> DataFrame { let symbols: Vec<i32> = Vec::new(); let prices: Vec<i32> = Vec::new(); df!( "Symbol" => &symbols, "Price" => &prices ).unwrap() } fn to_python() -> PyResult<PyDataFrame> { let df = get_df(); Ok(PyDataFrame(df)) }
如果需要直接转换为Python对象:
fn to_python_pyobject() -> PyResult<PyObject> { let df = get_df(); Python::with_gil(|py| { Ok(PyDataFrame(df).into_py(py)) }) }
内容的提问来源于stack exchange,提问作者Jun
相关产品推荐
相关产品推荐

