< 返回版块

/ 发表于 2024-12-22 19:38

Tags:排序, polars

在处理excel时,对数据最后汇总时,往往需要按照指定的字段值对表格进行排序,请问下这种在rust polars中如何实现,谢谢?

  • 比如:将结果按照公司部门字段的特定顺序对整个表格进行排序:营销部、后勤部、综合部、网络部的顺序对整个表格结果进行重排序

评论区

写评论
作者 / 2024-12-23 02:01

(⊙v⊙)嗯(⊙v⊙)嗯😂

--
👇
TinusgragLin: > 数量那个试了下将df["b"]中多加了一个"t"元素,报数量错误了,它这个估计是一一对应的: Error: ShapeMismatch(ErrString("could not create a new DataFrame: series 3 has length 3 while series "b" has length 4"))

我这边正常的:

fn main() -> Result<(), PolarsError> {
    let df = df![
        "a" => [1, 2, 3, 4],
        "b" => ["t", "y", "z", "t"]
    ]?;

    let s: Series = ["y", "t", "z"].iter().copied().collect();
    let t: Series = [1, 2, 3].iter().collect();
    let sorted = df
        .lazy()
        .sort_by_exprs(
            [col("b").replace(s.lit(), t.lit())],
            SortMultipleOptions::default(),
        )
        .collect()?;

    println!("{sorted}");
    Ok(())
}

输出:

shape: (4, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i32 ┆ str │
╞═════╪═════╡
│ 2   ┆ y   │
│ 1   ┆ t   │
│ 4   ┆ t   │
│ 3   ┆ z   │
└─────┴─────┘

那个报错是不是因为你忘记给 a 列加数据了?

TinusgragLin 2024-12-23 01:36

数量那个试了下将df["b"]中多加了一个"t"元素,报数量错误了,它这个估计是一一对应的: Error: ShapeMismatch(ErrString("could not create a new DataFrame: series 3 has length 3 while series "b" has length 4"))

我这边正常的:

fn main() -> Result<(), PolarsError> {
    let df = df![
        "a" => [1, 2, 3, 4],
        "b" => ["t", "y", "z", "t"]
    ]?;

    let s: Series = ["y", "t", "z"].iter().copied().collect();
    let t: Series = [1, 2, 3].iter().collect();
    let sorted = df
        .lazy()
        .sort_by_exprs(
            [col("b").replace(s.lit(), t.lit())],
            SortMultipleOptions::default(),
        )
        .collect()?;

    println!("{sorted}");
    Ok(())
}

输出:

shape: (4, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i32 ┆ str │
╞═════╪═════╡
│ 2   ┆ y   │
│ 1   ┆ t   │
│ 4   ┆ t   │
│ 3   ┆ z   │
└─────┴─────┘

那个报错是不是因为你忘记给 a 列加数据了?

作者 / 2024-12-23 01:27

感谢,问题基本解决了,数量那个试了下将df["b"]中多加了一个"t"元素,报数量错误了,它这个估计是一一对应的: Error: ShapeMismatch(ErrString("could not create a new DataFrame: series 3 has length 3 while series "b" has length 4"))

--
👇
TinusgragLin: > lazy知道,但是replace是在哪儿定义的呀?

我从文档这里看到的,可以看到需要 replace feature,在 cargo.toml 里加上就好了:

[dependencies]
polars = { version = "0.45.1", features = ["lazy", "replace"] }

另外还有个疑惑:目前这个新序s中的元素个数和df["b"]中元素个数是一致的,如果df["b"]中元素个数有多个重复值呢?

我的理解是,排序操作这里用到的这个 replace,语义就是“值替换”,就是 b 列中的所有的 “y” 值替换成 1,“t”值替换成 2,以此类推。

TinusgragLin 2024-12-23 01:19

lazy知道,但是replace是在哪儿定义的呀?

我从文档这里看到的,可以看到需要 replace feature,在 cargo.toml 里加上就好了:

[dependencies]
polars = { version = "0.45.1", features = ["lazy", "replace"] }

另外还有个疑惑:目前这个新序s中的元素个数和df["b"]中元素个数是一致的,如果df["b"]中元素个数有多个重复值呢?

我的理解是,排序操作这里用到的这个 replace,语义就是“值替换”,就是 b 列中的所有的 “y” 值替换成 1,“t”值替换成 2,以此类推。

作者 / 2024-12-23 01:00

另外还有个疑惑:目前这个新序s中的元素个数和df["b"]中元素个数是一致的,如果df["b"]中元素个数有多个重复值呢?

--
👇
TinusgragLin: 刚才忘记提了,要启用 lazyreplace feature。

作者 / 2024-12-23 00:57

lazy知道,但是replace是在哪儿定义的呀?

--
👇
TinusgragLin: 刚才忘记提了,要启用 lazyreplace feature。

TinusgragLin 2024-12-23 00:44

刚才忘记提了,要启用 lazyreplace feature。

作者 / 2024-12-23 00:18

请问下这块的报错的目的是做啥?以及这个报错是怎么处理的?

error[E0599]: no method named `replace` found for enum `Expr` in the current scope
   --> src/main.rs:33:23
    |
33  |             [col("b").replace(s.lit(), t.lit())],
    |                       ^^^^^^^ method not found in `Expr`
    |

--
👇
TinusgragLin: 我搜了一下,似乎可以用 python API 这样搞:

sort_list = ['c', 'b', 'a']
your_order = {v: idx for idx, v in enumerate(sort_list)} #{'c': 0, 'b': 1, 'a': 2}
final = df.sort(pl.col("c").replace(your_order))

我试着这样转译到 Rust API:

fn main() -> Result<(), PolarsError> {
    let df = df![
        "a" => [1, 2, 3],
        "b" => ["t", "y", "z"]
    ]?;

    let s: Series = ["y", "t", "z"].iter().copied().collect();
    let t: Series = [1, 2, 3].iter().collect();
    let sorted = df
        .lazy()
        .sort_by_exprs(
            [col("b").replace(s.lit(), t.lit())],
            SortMultipleOptions::default(),
        )
        .collect()?;

    println!("{sorted}");
    Ok(())
}

输出:

shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i32 ┆ str │
╞═════╪═════╡
│ 2   ┆ y   │
│ 1   ┆ t   │
│ 3   ┆ z   │
└─────┴─────┘

似乎可行

TinusgragLin 2024-12-22 23:21

我搜了一下,似乎可以用 python API 这样搞:

sort_list = ['c', 'b', 'a']
your_order = {v: idx for idx, v in enumerate(sort_list)} #{'c': 0, 'b': 1, 'a': 2}
final = df.sort(pl.col("c").replace(your_order))

我试着这样转译到 Rust API:

fn main() -> Result<(), PolarsError> {
    let df = df![
        "a" => [1, 2, 3],
        "b" => ["t", "y", "z"]
    ]?;

    let s: Series = ["y", "t", "z"].iter().copied().collect();
    let t: Series = [1, 2, 3].iter().collect();
    let sorted = df
        .lazy()
        .sort_by_exprs(
            [col("b").replace(s.lit(), t.lit())],
            SortMultipleOptions::default(),
        )
        .collect()?;

    println!("{sorted}");
    Ok(())
}

输出:

shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i32 ┆ str │
╞═════╪═════╡
│ 2   ┆ y   │
│ 1   ┆ t   │
│ 3   ┆ z   │
└─────┴─────┘

似乎可行

作者 / 2024-12-22 22:52

sort方法中目前感觉只能升序或者降序,但是需要的是指定特定的顺序,python的pandas中是自定义一个有序数列,然后排序时会根据自定义的有序数列对整个dataframe的记录进行排序,但是rust中的polars不知道怎么整

--
👇
PrivateRookie: 可以直接用sort方法 文档

PrivateRookie 2024-12-22 22:40

可以直接用sort方法 文档

1 共 11 条评论, 1 页