
本文介绍使用 Polars 一行 filter() 链式表达式,精准筛选出数值列中严格大于和小于目标值的各一个最邻近行,避免分步计算与 vstack 合并,兼顾简洁性与性能。
本文介绍使用 polars 一行 `filter()` 链式表达式,精准筛选出数值列中严格大于和小于目标值的各一个最邻近行,避免分步计算与 `vstack` 合并,兼顾简洁性与性能。
在量化分析、插值查找或期权行权价匹配等场景中,常需从有序数值列(如 strike)中快速定位紧邻目标值的上下界行——即差值 diff = strike - target 中,满足 diff 0 的最小值(上界)。Polars 提供了向量化、惰性求值的高性能能力,完全可在单次 filter() 中完成该逻辑,无需拆分、聚合再拼接。
核心思路是:利用布尔逻辑组合两个条件——
- diff == diff.filter(diff > 0).min():找到所有等于「正向差值最小值」的行(即首个大于目标的行);
- diff == diff.filter(diff 二者用 |(OR)连接,即可一次性筛选出两条目标行。
以下为完整可运行示例:
import polars as pl
data = {"strike": [5, 10, 15, 20, 25, 30]}
target = 16
diff_expr = pl.col("strike") - target
result = (
pl.DataFrame(data)
.filter(
(diff_expr == diff_expr.filter(diff_expr > 0).min()) |
(diff_expr == diff_expr.filter(diff_expr <p>输出:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/ai/1960" title="小羊标书"><img
src="https://img.php.cn/upload/ai_manual/000/000/000/175680456053464.png" alt="小羊标书" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/ai/1960" title="小羊标书" class="overflowclass">小羊标书</a>
<p class="overflowclass">一键生成百页标书,让投标更简单高效</p>
</div>
<a rel="nofollow" href="/ai/1960" title="小羊标书" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><pre class="brush:php;toolbar:false;">shape: (2, 3)
┌────────┬────────┬──────┐
│ strike ┆ target ┆ diff │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 │
╞════════╪════════╪══════╡
│ 15 ┆ 16 ┆ -1 │
│ 20 ┆ 16 ┆ 4 │
└────────┴────────┴──────┘✅ 优势说明:
- 零中间变量:不创建 df1/df2,无 vstack 或 concat 操作;
- 单次扫描逻辑:filter() 内部自动优化,Polars 推荐此模式替代多次子查询;
- 健壮性增强:若数据中不存在正/负差值(如全部 ≥ 或 ≤ 目标),对应 .min()/.max() 将返回 null,此时该分支不匹配——你可根据业务需要添加 coalesce() 或预检查;
- 可扩展性强:支持多列关联(如添加 target 列)、分组内查找(加 .over("group")),或结合 sort().head(1) 实现更复杂排序逻辑。
⚠️ 注意事项:
- 此方法依赖 strike 列已自然有序(如本例递增)。若无序,建议先 sort("strike") 再执行,否则“最近”语义可能失效;
- 若存在重复 strike 值且对应相同 diff,可能返回多于两行(例如两个 strike=15 同时满足 diff == -1)。此时可追加 .unique(subset="strike", keep="first") 去重;
- 对超大规模数据,diff.filter(...).min() 会触发局部计算,但仍在 Polars 优化器可控范围内,性能远优于 Python 循环或 Pandas apply。
综上,该方案以声明式、函数式风格实现了清晰、高效、可维护的邻近行检索,是 Polars 数据管道中处理“上下界查找”问题的推荐实践。










