rust 极:如何通过引用传递函数“is_in”的“other”参数?

ttp71kqs  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(135)

我是非常新的 rust ,所以请原谅我,如果这是一个微不足道的问题。
我正在尝试按如下方式筛选 Dataframe :

let allowed = Series::from_iter(vec![
        "string1".to_string(),
        "string2".to_string(),
    ]);
    let df = LazyCsvReader::new(&fullpath)
        .has_header(true)
        .finish().unwrap()
        .filter(col("string_id").is_in(&allowed)).collect().unwrap();

在我看来这很不错,因为is_in方法的签名看起来像这样:

fn is_in(
    &self,
    _other: &Series
) -> Result<ChunkedArray<BooleanType>, PolarsError>

来自[https://docs.rs/polars/latest/polars/series/trait.html#method.is_in]
但是,当我编译它时,我得到了以下错误:

error[E0277]: the trait bound `Expr: From<&polars::prelude::Series>` is not satisfied
    --> src/main.rs:33:40
     |
33   |         .filter(col("string_id").is_in(&allowed)).collect().unwrap();
     |                                  ----- ^^^^^^^^ the trait `From<&polars::prelude::Series>` is not implemented for `Expr`
     |                                  |
     |                                  required by a bound introduced by this call
     |
     = help: the following other types implement trait `From<T>`:
               <Expr as From<&str>>
               <Expr as From<AggExpr>>
               <Expr as From<bool>>
               <Expr as From<f32>>
               <Expr as From<f64>>
               <Expr as From<i32>>
               <Expr as From<i64>>
               <Expr as From<u32>>
               <Expr as From<u64>>
     = note: required for `&polars::prelude::Series` to implement `Into<Expr>`
note: required by a bound in `polars_plan::dsl::<impl Expr>::is_in`
    --> /home/myself/.cargo/registry/src/
     |
1393 |     pub fn is_in<E: Into<Expr>>(self, other: E) -> Self {
     |                     ^^^^^^^^^^ required by this bound in `polars_plan::dsl::<impl Expr>::is_in`

For more information about this error, try `rustc --explain E0277`.

在我看来,这个错误看起来很神秘。我读到rustc --explain E0277的结果说:“你试图使用一个类型,它不实现一些trait在一个地方,期望该trait”,但这丝毫没有帮助识别哪个类型不实现哪个trait.

  • “* 我该怎么补救,为什么不管用**

注意:我知道用lit(allowed)代替&allowed是可行的,但这是不可能的,因为它会阻止在其他地方使用allowed。例如,我想做以下事情,但下面的代码得到了一个错误“use of moved value”(显然):

let df = LazyCsvReader::new(&fullpath)
        .has_header(true)
        .finish().unwrap()
        .with_column(
            when(
                col("firstcolumn").is_in(lit(allowed))
                    .and(
                    col("secondcolumn").is_in(lit(allowed))
                    )
                )
                .then(lit("very good"))
                .otherwise(lit("very bad"))
                .alias("good_bad")
        )
        .collect().unwrap();

附加问题:

  • 为什么lit(allowed)可以使用?我不应该按照文档中的说明通过引用传递变量吗?
  • 如何像上面的示例一样重复使用is_in系列而不出现错误?

编辑:我发现is_in的另一个签名要求第二个参数为Expr,这将证明使用lit的必要性。然而,仍然不清楚如何多次使用同一个Series而不出现借用值错误。

j8ag8udp

j8ag8udp1#

签名是针对Series.is_in()的,但您使用的是不同的www.example.com_in()。Expr.is_in() which differs.
可以使用cols()选择多个列:

.with_columns([
    cols(["firstcolumn", "secondcolumn"]).is_in(lit(allowed))
])
┌─────────────┬──────────────┬─────────────┐
│ firstcolumn ┆ secondcolumn ┆ thirdcolumn │
│ ---         ┆ ---          ┆ ---         │
│ bool        ┆ bool         ┆ str         │
╞═════════════╪══════════════╪═════════════╡
│ false       ┆ false        ┆ moo         │
│ true        ┆ false        ┆ foo         │
│ true        ┆ true         ┆ keepme      │
│ true        ┆ true         ┆ andme       │
└─────────────┴──────────────┴─────────────┘

.when()内部使用-存在隐式AND

┌─────────────┬──────────────┬─────────────┬───────────┐
│ firstcolumn ┆ secondcolumn ┆ thirdcolumn ┆ good_bad  │
│ ---         ┆ ---          ┆ ---         ┆ ---       │
│ str         ┆ str          ┆ str         ┆ str       │
╞═════════════╪══════════════╪═════════════╪═══════════╡
│ a           ┆ b            ┆ moo         ┆ very bad  │
│ string1     ┆ no           ┆ foo         ┆ very bad  │
│ string2     ┆ string1      ┆ keepme      ┆ very good │
│ string1     ┆ string2      ┆ andme       ┆ very good │
└─────────────┴──────────────┴─────────────┴───────────┘

关于移动值错误-我对rust知之甚少,但编译器告诉我:

help: consider cloning the value if the performance cost is acceptable
   |
15 |                 col("firstcolumn").is_in(lit(allowed.clone())).and(col("secondcolumn").is_in(lit(allowed))))
   |                                                     ++++++++

cloning a Series is a super cheap operation.

相关问题