在 Rust 中逐行高效地构建 Polars DataFrame

Efficiently build a Polars DataFrame row by row in Rust

我想使用 Rust 创建一个大型 Polars DataFrame,使用从网页上抓取的数据逐行构建它。执行此操作的有效方法是什么?

看起来 DataFrame 应该从 SeriesVec 创建,而不是向空 DataFrame 添加行。但是,一个Series应该如何高效的搭建起来呢?我可以创建一个 Vec,然后从 Vec 创建一个 Series,但这听起来像是最终会复制所有元素。有没有一种方法可以逐个元素地构建一个 Series,然后从中构建一个 DataFrame

实际上,我将使用 Rayon 并行构建多个 DataFrame,然后将它们组合起来,但看起来 vstack 可以满足我的要求。我不知道如何有效地创建单个 DataFrames。

我确实查看了 CSV 解析器的源代码,但它非常复杂,而且可能经过高度优化,但是否有一种仍然相当有效的简单方法?

pub fn from_vec(
    name: &str,
    v: Vec<<T as PolarsNumericType>::Native, Global>
) -> ChunkedArray<T>

Create a new ChunkedArray by taking ownership of the Vec. This operation is zero copy.

here就是link。然后你可以在上面调用 into_series

最简单的答案,如果不是最高效的话,就是只维护一张向量图,然后将它们转换成序列,然后一次性全部输入 DataFrame。

let columns = BTreeMap::new();
for datum in get_data_from_web() {
    // For simplicity suppose datum is itself a BTreeMap
    // (More likely it's a serde_json::Value)
    // It's assumed that every datum has the same keys; if not, the 
    // Vecs won't have the same length
    // It's also assumed that the values of datum are all of the same known type

    for (k, v) in datum {
        columns.entry(k).or_insert(vec![]).push(v);
    }
}

let df = DataFrame::new(
    columns.into_iter()
        .map(|(name, values)| Series::new(name, values))
        .collect::<Vec<_>>()
    ).unwrap();