Rust Polars 迭代 ChunckedArray<StructType>

问题描述 投票:0回答:1

我正在关注这个answer,但它在我的版本上对我不起作用(polar = { version =“0.42.0”,features = [“dtype-struct”,“lazy”,“polars-io”] })。我看到在新版本中

into_struct
返回
ChunckedArray<StructType>
而不是
StructChuncked
。令人惊讶的是,新版本中的
iter
给出了看起来没用的
Option<()>
。这是否意味着不可能迭代
ChunckedArray<StructType>
?或者有不同的方法吗?另外,如果您知道该更改背后的动机,我很高兴了解这一点。

rust-polars
1个回答
0
投票
[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(),
        }
        );
    }
© www.soinside.com 2019 - 2024. All rights reserved.