如何从Vec<Struct>类型的结构体向量创建列名匹配字段的Polars DataFrame
如何将Rust结构体向量转换为Polars DataFrame?
当然有办法啦!而且实现起来还挺简单的,有两种常见的方式可以搞定这个需求,保证DataFrame的列名和结构体字段名完全对应,我给你详细讲讲:
方法一:使用Polars的派生宏(推荐)
这种方式最简洁,只需要给你的结构体加上Polars提供的派生宏,就能直接把结构体向量转成DataFrame。
首先你需要在Cargo.toml里添加带derive特性的Polars依赖:
[dependencies] polars = { version = "0.35", features = ["derive", "fmt"] }
然后修改你的代码,给结构体添加DerivePolarsStruct派生宏,之后就能用DataFrame::from_iter完成转换:
use polars::prelude::*; #[derive(Debug, Clone, DerivePolarsStruct)] struct Test { id: u32, amount: u32 } fn main() { let test_vec: Vec<Test> = vec![Test{id:1, amount:3}, Test{id:3, amount:4}]; // 转换为DataFrame,自动匹配字段名为列名 let df = DataFrame::from_iter(test_vec).unwrap(); // 打印结果 println!("{}", df); }
运行后你会得到这样的输出:
shape: (2, 2) ┌─────┬────────┐ │ id ┆ amount │ │ --- ┆ --- │ │ u32 ┆ u32 │ ╞═════╪════════╡ │ 1 ┆ 3 │ ├─────┼────────┤ │ 3 ┆ 4 │ └─────┴────────┘
方法二:手动提取字段构建DataFrame
如果你不想使用派生宏,也可以手动提取结构体的每个字段,单独构建序列后再组合成DataFrame,这种方式更灵活,适合需要对字段做额外处理的场景:
use polars::prelude::*; struct Test { id: u32, amount: u32 } fn main() { let test_vec: Vec<Test> = vec![Test{id:1, amount:3}, Test{id:3, amount:4}]; // 分别提取id和amount字段的向量 let ids: Vec<u32> = test_vec.iter().map(|t| t.id).collect(); let amounts: Vec<u32> = test_vec.iter().map(|t| t.amount).collect(); // 用df!宏构建DataFrame,指定列名和对应序列 let df = df!( "id" => ids, "amount" => amounts ).unwrap(); println!("{}", df); }
这个代码运行后的输出和第一种方法完全一致。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

