You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将Rust创建的Polars DataFrame传递给Python且避免拷贝?

Rust 侧持有 Polars DataFrame,供 Python 插件只读访问的方案

完全可行,核心思路是通过引用共享+自定义PyO3包装类型,让Python仅获得DataFrame的访问权,而所有权始终留在Rust侧,避免拷贝/移动数据。

关键实现要点

  • 用Arc<DataFrame>包装Rust侧的DataFrame,利用原子引用计数实现安全的跨语言共享,Rust始终持有所有权。
  • 基于PyO3自定义PyClass类型,将Arc<DataFrame>封装在内部,仅暴露只读访问方法给Python,禁止所有权转移。
  • 无需依赖pyo3-polars的默认转换逻辑(该逻辑确实会触发数据拷贝),自定义包装可以完全控制数据流向。

示例代码片段

Rust 侧(核心实现)

use pyo3::prelude::*;
use polars::prelude::*;
use std::sync::Arc;

// 自定义Python可访问的DataFrame包装类,仅持有Rust侧DataFrame的共享引用
#[pyclass]
struct SharedDataFrame {
    inner: Arc<DataFrame>,
}

#[pymethods]
impl SharedDataFrame {
    // 暴露只读属性:获取行数
    #[getter]
    fn row_count(&self) -> usize {
        self.inner.height()
    }

    // 读取指定列的数据(返回拷贝后的Vec,若仅需计算可在Rust侧完成以避免拷贝)
    fn get_column(&self, col_name: &str) -> PyResult<Vec<Option<f64>>> {
        let col = self.inner.column(col_name)?;
        let series = col.f64()?;
        Ok(series.into_iter().collect())
    }

    // 在Rust侧执行计算,直接返回结果,数据全程不离开Rust
    fn sum_column(&self, col_name: &str) -> PyResult<Option<f64>> {
        let col = self.inner.column(col_name)?;
        Ok(col.sum())
    }
}

// 初始化Python插件模块
#[pymodule]
fn rust_polars_ext(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_class::<SharedDataFrame>()?;
    
    // 示例:提供一个从Rust侧创建并返回SharedDataFrame的函数
    #[pyfn(m)]
    fn create_test_dataframe(_py: Python) -> SharedDataFrame {
        let df = df!(
            "id" => [1, 2, 3, 4],
            "value" => [10.5, 20.7, 30.2, 40.9]
        ).unwrap();
        SharedDataFrame { inner: Arc::new(df) }
    }

    Ok(())
}

Python 侧(插件使用)

import rust_polars_ext

# 从Rust侧获取共享的DataFrame包装实例
df = rust_polars_ext.create_test_dataframe()

# 访问只读属性
print(f"行数: {df.row_count()}")

# 读取列数据(按需拷贝,若仅做计算建议调用Rust侧方法)
values = df.get_column("value")
print(f"value列数据: {values}")

# 直接调用Rust侧的计算逻辑,数据不离开Rust
sum_val = df.sum_column("value")
print(f"value列求和: {sum_val}")

注意事项

  • 线程安全:Polars的DataFrame默认是不可变的,结合Arc可安全跨线程、跨语言共享;若需支持修改,可改用Arc<RwLock<DataFrame>>,但需注意同步逻辑。
  • 只读约束:通过仅暴露只读方法,确保Python无法修改Rust侧的原始DataFrame,完全符合“数据留存于Rust侧”的需求。
  • 性能优化:对于复杂计算,尽量在Rust侧实现后暴露结果给Python,避免大量数据拷贝开销。

内容的提问来源于stack exchange,提问作者nu11ptr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:08:26