设置allow_exact_matches=False后,join_asof()仍返回精确匹配的原因?
Polars 1.35.2中join_asof nearest策略下allow_exact_matches=False未生效的问题
这不是bug,是Polars 1.35.2版本里join_asof使用strategy="nearest"时的已知行为——当执行自连接时,allow_exact_matches=False无法过滤掉精确匹配的行。原因是nearest策略的逻辑优先级更高,自连接场景下每一行的精确匹配项会被直接判定为"最近",导致allow_exact_matches的限制未生效。
解决办法
要获取最近的非精确匹配,可以在连接完成后手动过滤掉精确匹配的行:
import polars as pl df = pl.from_repr(""" ┌─────┬────────────┐ │ uid ┆ dates │ │ --- ┆ --- │ │ i64 ┆ date │ ╞═════╪════════════╡ │ 1 ┆ 2025-11-21 │ │ 2 ┆ 2025-11-22 │ │ 3 ┆ 2025-11-23 │ │ 4 ┆ 2025-11-24 │ │ 5 ┆ 2025-11-25 │ └─────┴────────────┘ """) # 自连接后过滤精确匹配项 self_join = df.join_asof( df, on="dates", strategy="nearest", allow_exact_matches=False, coalesce=False, ).filter(pl.col("dates") != pl.col("dates_right")) print(self_join)
执行后的结果会正确移除精确匹配:
┌─────┬────────────┬───────────┬─────────────┐ │ uid ┆ dates ┆ uid_right ┆ dates_right │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ date ┆ i64 ┆ date │ ╞═════╪════════════╪═══════════╪═════════════╡ │ 1 ┆ 2025-11-21 ┆ 2 ┆ 2025-11-22 │ │ 2 ┆ 2025-11-22 ┆ 1 ┆ 2025-11-21 │ │ 2 ┆ 2025-11-22 ┆ 3 ┆ 2025-11-23 │ │ 3 ┆ 2025-11-23 ┆ 2 ┆ 2025-11-22 │ │ 3 ┆ 2025-11-23 ┆ 4 ┆ 2025-11-24 │ │ 4 ┆ 2025-11-24 ┆ 3 ┆ 2025-11-23 │ │ 4 ┆ 2025-11-24 ┆ 5 ┆ 2025-11-25 │ │ 5 ┆ 2025-11-25 ┆ 4 ┆ 2025-11-24 │ └─────┴────────────┴───────────┴─────────────┘
如果需要每行仅保留一个最近的非精确匹配,可以进一步筛选唯一值:
self_join_unique = self_join.with_columns( (pl.col("dates") - pl.col("dates_right")).abs().alias("date_diff") ).sort("date_diff").group_by("uid", "dates").first() print(self_join_unique)
额外说明
这个行为可能在Polars后续版本中被优化,你可以留意官方更新日志查看参数逻辑是否调整。
内容的提问来源于stack exchange,提问作者rainerpf
相关产品推荐
相关产品推荐

