首页 > 解决方案 > Rust:从 mysql 读取 Polars 中的数据框

问题描述

问题

如何从 mysql 读取 Polars 中的数据框。 文档对这个问题保持沉默。目前可能只支持 parquet、json、ipc 等,没有直接支持这里sql提到的。

无论使用以下库读取数据的合适方法是什么:sqlxmysql

当前方法

目前,我正在遵循此答案中提供的这种方法:

  1. 读入Vec<Struct>使用sqlx
  2. (Vec<T>, Vec<T>)使用下面的代码将其转换为 vecs 元组
  3. 转换(Vec<T>, Vec<T>)(Series, Series)
  4. 使用创建数据框DataFrame::new(vec![s0, s1]):在哪里s0s1在哪里Series
struct A(u8, i8);

fn main() {
    let v = vec![A(1, 4), A(2, 6), A(3, 5)];

    let result = v.into_iter()
        .fold((vec![], vec![]), |(mut u, mut i), item| {
            u.push(item.0);
            i.push(item.1);
            (u, i)
        });
    
    dbg!(result);

    // `result` is just a tuple of vectors
    // let (unsigneds, signeds): (Vec<u8>, Vec<i8>) = result;
}

标签: mysqldataframerustrust-sqlxrust-polars

解决方案


与此问题相同的答案,似乎与 IMO 完全重复。

您可以为此使用构建器或从迭代器中收集。从迭代器中收集通常很快,但在这种情况下,它需要您循环Vec<Country>两次,因此您应该进行基准测试。

下面是显示的两种解决方案的示例函数。

use polars::prelude::*;

struct Country {
    country: String,
    count: i64,
}

fn example_1(values: &[Country]) -> (Series, Series) {
    let ca_country: Utf8Chunked = values.iter().map(|v| &*v.country).collect();
    let ca_count: NoNull<Int64Chunked> = values.iter().map(|v| v.count).collect();
    let mut s_country: Series = ca_country.into();
    let mut s_count: Series = ca_count.into_inner().into();
    s_country.rename("country");
    s_count.rename("country");
    (s_count, s_country)
}

fn example_2(values: &[Country]) -> (Series, Series) {
    let mut country_builder = Utf8ChunkedBuilder::new("country", values.len(), values.len() * 5);
    let mut count_builder = PrimitiveChunkedBuilder::<Int64Type>::new("count", values.len());

    values.iter().for_each(|v| {
        country_builder.append_value(&v.country);
        count_builder.append_value(v.count)
    });

    (
        count_builder.finish().into(),
        country_builder.finish().into(),
    )
}

获得 后Series,您可以使用DataFrame::new(columns)wherecolumns: Vec<Series>创建DataFrame.

顺便说一句,如果你想要最大的性能,我真的推荐connector-x。它具有极地和箭头集成,并具有疯狂的性能。


推荐阅读