
本文介绍如何在 polars 中高效筛选距离指定日期最近的行,无需创建临时列,通过链式表达式直接完成过滤,兼顾可读性与性能。
本文介绍如何在 polars 中高效筛选距离指定日期最近的行,无需创建临时列,通过链式表达式直接完成过滤,兼顾可读性与性能。
在数据处理中,常需从时间序列 DataFrame 中提取“离目标日期最近”的记录(如查找某日最近的行情、日志或快照)。Polars 提供了高性能的表达式 API,完全支持在不显式添加辅助列的前提下完成此类筛选——关键在于合理利用 min() 聚合与布尔广播比较。
以下为完整示例(基于你提供的数据):
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(
(pl.col("date") - target_date).abs().min() == (pl.col("date") - target_date).abs()
)
print(result)
输出:
shape: (3, 2) ┌────────────┬───────┐ │ date ┆ value │ │ --- ┆ --- │ │ date ┆ i64 │ ╞════════════╪═══════╡ │ 2025-01-01 ┆ 1 │ │ 2025-01-01 ┆ 2 │ │ 2025-01-01 ┆ 3 │ └────────────┴───────┘
原理说明:
-
(pl.col("date") - target_date).abs()计算每行日期与目标日期的绝对差值(返回Expr); -
.min()对该差值表达式执行聚合,得到全局最小差值(标量); - Polars 自动将标量
min()结果广播为与原 Series 等长的布尔掩码,从而完成精准过滤。
⚠️ 注意事项:
- 日期列必须为
Date或Datetime类型(如本例中已用.str.to_date()转换),否则减法操作会报错;- 若存在多个相同最小差值的日期(如本例中三行同为
2025-01-01),所有匹配行均被保留,符合“最近且全部返回”的业务预期;- 该写法零冗余列、无中间赋值,内存友好,适合嵌入复杂查询链(如
lazy().filter(...).select(...))。
进阶提示:若需仅取一行(如严格取第一条最近记录),可改用 sort_by(...).head(1);若需返回差值本身用于调试,再加 .with_columns(diff=...) 即可——灵活性由需求驱动,核心逻辑始终简洁如一。










