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

如何在Polars中基于date+多字段OR条件实现DataFrame连接?

在Polars中实现多字段OR逻辑的连接需求

完全可以实现。你需要先基于date字段对齐数据,再通过org_id、org_slug、org_name的OR条件匹配,同时处理空值避免无效匹配。以下是两种高效的实现方式:

方法一:使用Join的Condition参数(推荐)

Polars的join方法支持通过condition参数指定额外的匹配逻辑,结合on="date"先对齐日期,再在同日期范围内应用OR条件。同时加入is_not_null判断,避免空值之间的错误匹配。

示例代码

import polars as pl

# 构造示例数据集
df1 = pl.DataFrame({
    "date": ["2024-01-01", "2024-01-01", "2024-01-02"],
    "org_id": [1, None, 3],
    "org_slug": ["abc", "def", None],
    "org_name": ["Org A", "Org B", "Org C"],
    "value1": [10, 20, 30]
})

df2 = pl.DataFrame({
    "date": ["2024-01-01", "2024-01-01", "2024-01-02"],
    "org_id": [1, 2, None],
    "org_slug": ["abc", None, "org-c"],
    "org_name": ["Org A", "Org B", "Org C"],
    "value2": [100, 200, 300]
})

# 执行连接
result = df1.join(
    df2,
    on="date",
    how="inner",  # 根据需求选择连接类型:inner/left/right/full
    condition=(
        # org_id匹配(双方非空)
        (pl.col("org_id") == pl.col("org_id_right")) 
        & pl.col("org_id").is_not_null() 
        & pl.col("org_id_right").is_not_null()
        # 或org_slug匹配(双方非空)
        | (pl.col("org_slug") == pl.col("org_slug_right")) 
        & pl.col("org_slug").is_not_null() 
        & pl.col("org_slug_right").is_not_null()
        # 或org_name匹配(双方非空)
        | (pl.col("org_name") == pl.col("org_name_right")) 
        & pl.col("org_name").is_not_null() 
        & pl.col("org_name_right").is_not_null()
    )
)

print(result)

方法二:Cross Join + 过滤(适合小数据集)

如果数据集规模较小,可以先按date做笛卡尔积连接,再过滤符合OR条件的行。这种方式逻辑更直观,但数据量大时性能不如方法一。

示例代码

result = df1.join(
    df2,
    on="date",
    how="cross"
).filter(
    (pl.col("org_id") == pl.col("org_id_right")) & pl.col("org_id").is_not_null() & pl.col("org_id_right").is_not_null()
    | (pl.col("org_slug") == pl.col("org_slug_right")) & pl.col("org_slug").is_not_null() & pl.col("org_slug_right").is_not_null()
    | (pl.col("org_name") == pl.col("org_name_right")) & pl.col("org_name").is_not_null() & pl.col("org_name_right").is_not_null()
)

print(result)

进阶:优先匹配逻辑

如果需要优先用org_id匹配,其次是org_slug,最后是org_name(避免同一日期下出现多个匹配结果),可以通过添加匹配优先级并去重实现:

result = df1.join(
    df2,
    on="date",
    how="left"
).with_columns(
    # 给匹配条件设置优先级:1=org_id,2=org_slug,3=org_name
    pl.when((pl.col("org_id") == pl.col("org_id_right")) & pl.col("org_id").is_not_null()).then(1)
    .when((pl.col("org_slug") == pl.col("org_slug_right")) & pl.col("org_slug").is_not_null()).then(2)
    .when((pl.col("org_name") == pl.col("org_name_right")) & pl.col("org_name").is_not_null()).then(3)
    .alias("match_priority")
).filter(pl.col("match_priority").is_not_null())
.sort("match_priority")
.group_by(["date", "org_id", "org_slug", "org_name"])
.first()
.drop("match_priority")

print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:12:06