You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars Lazy API with_context过滤报错求助

Polars惰性API with_context 方法使用困惑及解决

问题描述

我搞不懂Polars惰性API里with_context方法的用法。官方文档说这个方法允许表达式访问不属于当前DataFrame的列,但我用另一个DataFrame的列过滤当前列时,会报错“其他DataFrame的列不存在”;换成select操作却能正常执行。

报错代码(main.rs)

use polars::prelude::*;

fn main() {
    let df0 = df! {
        "id" => [1, 2, 3],
        "name" => ["foo", "bar", "baz"],
    }
    .unwrap()
    .lazy();
    let other_df = df! {
        "other_id" => [1,2,2,1],
        "name" => ["w", "x", "y", "z"],
    }
    .unwrap()
    .lazy();

    let lf = df0.with_context(&[other_df]);
    let res = lf
        .filter(col("id").is_in(col("other_id")))
        .collect()
        .unwrap();
    println!("{:?}", res);
}

Cargo.toml依赖

[dependencies]
polars = {git = "https://github.com/pola-rs/polars", branch = "master", features = ["lazy", "is_in"]}

可正常执行的select替代代码

let res = lf
    .select(&[col("id").is_in(col("other_id"))])
    .collect()
    .unwrap();

问题原因

with_context的核心是允许表达式访问上下文列,但**filter操作要求逐行对齐当前DataFrame与上下文DataFrame的行**。你的示例中,df0有3行,other_df有4行,行数不匹配导致Polars无法完成行对齐,因此报错。

而select中的is_in操作逻辑不同:它会自动将上下文列other_id作为一个整体集合处理,判断当前DataFrame每行的id是否属于这个集合,不需要行对齐,因此能正常执行。

解决方案

方案1:提取上下文列的集合后过滤

先将上下文DataFrame的other_id提取为一个独立的集合,再用于过滤当前DataFrame:

use polars::prelude::*;

fn main() {
    let df0 = df! {
        "id" => [1, 2, 3],
        "name" => ["foo", "bar", "baz"],
    }
    .unwrap()
    .lazy();
    let other_df = df! {
        "other_id" => [1,2,2,1],
        "name" => ["w", "x", "y", "z"],
    }
    .unwrap();

    // 获取other_id的唯一值集合
    let other_ids = other_df.column("other_id").unwrap().unique().unwrap();

    let res = df0
        .filter(col("id").is_in(other_ids))
        .collect()
        .unwrap();
    println!("{:?}", res);
}

方案2:通过Join关联后过滤

使用内连接(Inner Join)关联两个DataFrame,再去重得到结果:

use polars::prelude::*;

fn main() {
    let df0 = df! {
        "id" => [1, 2, 3],
        "name" => ["foo", "bar", "baz"],
    }
    .unwrap()
    .lazy();
    let other_df = df! {
        "other_id" => [1,2,2,1],
        "name" => ["w", "x", "y", "z"],
    }
    .unwrap()
    .lazy();

    let res = df0
        .join(other_df, col("id"), col("other_id"), JoinType::Inner)
        .select(&[col("id"), col("name_left").alias("name")])
        .unique()
        .collect()
        .unwrap();
    println!("{:?}", res);
}

内容的提问来源于stack exchange,提问作者Cory Grinstead

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:35:19