
本文介绍如何在 Polars 中无需创建临时列,直接筛选出日期列中距离目标日期最近的所有行,利用链式表达式与 min() 聚合实现简洁高效的单行过滤。
本文介绍如何在 polars 中无需创建临时列,直接筛选出日期列中距离目标日期最近的所有行,利用链式表达式与 `min()` 聚合实现简洁高效的单行过滤。
在 Polars 中,当需要根据「距离指定日期最近」这一条件筛选 DataFrame 行时,核心思路是:计算每行日期与目标日期的绝对差值,再保留差值等于全局最小值的所有行。虽然常见做法是先用 with_columns 添加临时 diff 列再过滤,但 Polars 支持更紧凑、无副作用的纯表达式写法。
推荐方案如下(两种等效形式):
✅ 推荐写法(使用海象运算符 :=,简洁且仅一次计算):
import polars as pl
import datetime
data = {"date": ["2025-01-01", "2025-01-01", "2025-01-01", "2026-01-01"], "value": [1, 2, 3, 4]}
df = pl.DataFrame(data).with_columns(pl.col("date").str.to_date())
target_date = datetime.date(2024, 12, 31)
result = df.filter((m := (pl.col("date") - target_date).abs()).min() == m)
print(result)✅ 兼容性更强写法(显式定义变量,适用于所有 Python 版本):
diff = (pl.col("date") - target_date).abs()
result = df.filter(diff.min() == diff)⚠️ 关键注意事项:
-
diff.min()是一个标量聚合结果(Expr),而diff是长度为n_rows的列级表达式;Polars 会自动广播比较操作,语义等价于「对每一行判断其差值是否等于全局最小差值」; - 日期减法自动返回
duration类型,.abs()可安全作用于duration,无需手动转换为天数; - 若存在多个日期并列“最近”(如本例中三个
2025-01-01),该方法会全部保留,符合“最近”的集合语义; - 不依赖
with_columns,避免中间列污染原始逻辑,内存与可读性更优。
? 进阶提示: 若需仅取单条最近记录(例如取第一条),可在末尾追加 .limit(1);若需按差值升序+其他字段排序后取首行,可用 .sort(by=[diff, "value"]).limit(1)。
综上,通过复用同一 Expr 并结合聚合与逐行比较,Polars 实现了零临时列、高可读性、高性能的最近日期筛选——这是声明式数据处理范式的典型优势。

















