我正在关注这个answer,但它在我的版本上对我不起作用(polar = { version =“0.42.0”,features = [“dtype-struct”,“lazy”,“polars-io”] })。我看到在新版本中
into_struct
返回 ChunckedArray<StructType>
而不是 StructChuncked
。令人惊讶的是,新版本中的iter
给出了看起来没用的Option<()>
。这是否意味着不可能迭代ChunckedArray<StructType>
?或者有不同的方法吗?另外,如果您知道该更改背后的动机,我很高兴了解这一点。
[package]
name = "pol"
version = "0.1.0"
edition = "2021"
[dependencies]
polars = {version="0.43.0",features=["mode","polars-io","csv","polars-ops","lazy","docs-selection","streaming","regex","temporal","is_unique","is_between","dtype-date","dtype-datetime","dtype-time","dtype-duration","dtype-categorical","rows","is_in","pivot"]}
polars-io = "0.43.0"
polars-lazy = "0.43.0"
有.downcast_iter()可以用,但是需要操作Chunks。很复杂。 Polars源码中有一个操作Struct的函数,就是StructChunked::unnest(&self),用于对Struct打包的字段进行解包。我们来看看它的源代码。
let df_packed = df.clone().into_struct("fsh".into());
// df_packed.unnest(),Reversing into_struct().
let df_unstruct = df_packed.unnest();
println!("unstruct:\n{}", df_unstruct);
输出:
unstruct:
shape: (3, 3)
┌─────┬───────┬─────┐
│ id ┆ name ┆ age │
│ --- ┆ --- ┆ --- │
│ u32 ┆ str ┆ u32 │
╞═════╪═══════╪═════╡
│ 1 ┆ John ┆ 32 │
│ 2 ┆ Jane ┆ 28 │
│ 3 ┆ Bobby ┆ 45 │
└─────┴───────┴─────┘
// Polars Sources Code for "unnest"
pub fn unnest(self) -> DataFrame {
// SAFETY: invariants for struct are the same
unsafe { DataFrame::new_no_checks(self.fields_as_series()) }
}
pub fn fields_as_series(&self) -> Vec<Series> {
self.struct_fields()
.iter()
.enumerate()
.map(|(i, field)| {
let field_chunks = self
.downcast_iter()
.map(|chunk| chunk.values()[i].clone())
.collect::<Vec<_>>();
// SAFETY: correct type.
unsafe {
Series::from_chunks_and_dtype_unchecked(
field.name.clone(),
field_chunks,
&field.dtype,
)
}
})
.collect()
}
有.downcast_iter()可以用,但是需要操作Chunks。很复杂。 这个问题的本质是Struct没有用于dataframe的行迭代。 Struct用于将自定义函数的复杂结果封装成复杂聚合中的Series。 Polars行迭代由于涉及到很多类型转换,效率损失较大。
df.get_row(&self, idx: usize)
可用于按行工作,但速度较慢。
对于你的问题,只需使用for循环:
let id_ = objects[0].u32()?.to_vec();
let name_ = objects[1].str()?;
let age_=objects[2].u32()?.to_vec();
let mut res = Vec::with_capacity(3);
for i in 0..id_.len(){
res.push( Person{
id: id_[i].unwrap(),
name: name_.get(i).unwrap().to_string(),
age: age_[i].unwrap(),
}
);
}