如何序列化/反序列化Polars DataFrame以通过REST调用传输?
在Rust中序列化/反序列化Polars DataFrame为Arrow二进制格式
在Rust中,Polars没有提供Python那样的顶层to_arrow()/from_arrow()方法,但可以通过与Arrow生态的交互实现需求——核心是借助Polars的Arrow转换API,搭配官方arrow和arrow-ipc库完成二进制序列化。
依赖配置
首先在Cargo.toml中添加所需依赖,注意保持Arrow相关库版本与Polars依赖的Arrow版本兼容:
[dependencies] polars = { version = "0.35", features = ["arrow"] } arrow = "51.0" arrow-ipc = "51.0" bytes = "1.5"
序列化:DataFrame转Arrow二进制
将Polars DataFrame转换为Arrow RecordBatch,再通过Arrow IPC写入器序列化为二进制数据:
use polars::frame::DataFrame; use arrow::ipc::writer::StreamWriter; use bytes::BytesMut; fn serialize_df_to_arrow(df: &DataFrame) -> Result<Vec<u8>, Box<dyn std::error::Error>> { // Polars DataFrame转Arrow RecordBatch let batch = df.to_arrow_record_batch()?; // 内存缓冲区存储序列化结果 let mut buffer = BytesMut::new(); // 初始化Arrow IPC流写入器 let mut writer = StreamWriter::try_new(&mut buffer, batch.schema())?; // 写入批次并完成序列化 writer.write(&batch)?; writer.finish()?; Ok(buffer.into()) }
反序列化:Arrow二进制转DataFrame
通过Arrow IPC读取器解析二进制数据,再转换回Polars DataFrame:
use polars::frame::DataFrame; use arrow::ipc::reader::StreamReader; use std::io::Cursor; fn deserialize_arrow_to_df(arrow_data: &[u8]) -> Result<DataFrame, Box<dyn std::error::Error>> { // 创建游标读取二进制数据 let cursor = Cursor::new(arrow_data); // 初始化Arrow IPC流读取器 let mut reader = StreamReader::try_new(cursor)?; // 读取首个RecordBatch(多批次场景需循环读取并合并) let batch = reader.next().ok_or("no record batch found")??; // Arrow RecordBatch转Polars DataFrame let df = DataFrame::from_arrow_record_batch(&batch)?; Ok(df) }
补充说明
- 若处理超大数据集,Polars会将DataFrame拆分为多个RecordBatch,此时序列化需循环写入所有批次,反序列化需循环读取后用
DataFrame::extend()合并。 - 示例使用Arrow IPC流式模式,若需文件格式可改用
FileWriter/FileReader。 - Arrow二进制格式为列存储结构,无需文本解析,性能远优于JSON/CSV,适合REST传输场景。
内容的提问来源于stack exchange,提问作者JavaTechnical
相关产品推荐
相关产品推荐

