如何在Polars中获取日期/日期时间对象而非表达式类型?
使用Polars实现日期循环的正确方式
问题背景
需要用Polars声明date/datetime类型的起止日期变量,运行while循环(循环条件为startdate <= enddate),每次循环将startdate增加一天。此前使用pl.date()的尝试报错,对比Pandas的实现可正常运行,需适配Polars语法完成需求。
错误尝试代码
import polars as pl startdate = pl.date(year=2023, month=1, day=1) enddate = pl.date(year=2023, month=1, day=10) frequency = pl.duration(days=1) i=0 while startdate <= enddate: print(i) i += 1 startdate += frequency
报错信息
ValueError: Since Expr are lazy, the truthiness of an Expr is ambiguous. Hint: use '&' or '|' to logically combine Expr, not 'and'/'or', and use 'x.is_in([y,z])' instead of 'x in [y,z]' to check membership.
Pandas参考实现
import pandas as pd startdate = pd.to_datetime('2023-01-01') enddate = pd.to_datetime('2023-01-03') frequency = pd.to_timedelta(1,'d') i=0 while startdate <= enddate: print(i) i += 1 startdate += frequency
参考输出
0 1 2
问题原因
pl.date()是Polars中用于创建**表达式(Expr)**的函数,返回的是惰性求值的Expr对象,无法直接用于while循环的布尔判断(Expr的真值具有模糊性,Polars不允许直接将Expr作为布尔条件)。而Pandas的pd.to_datetime()返回的是具体的datetime对象,可直接进行比较运算。
解决方案
需要创建Polars的标量日期对象(而非表达式),以下是几种可行方式:
方式1:使用pl.Date/pl.Datetime标量构造函数
直接调用首字母大写的pl.Date(纯日期类型)或pl.Datetime(带时间的日期类型)构造函数,返回具体的标量值,支持直接比较和运算。
纯日期类型(Date)示例代码
import polars as pl # 创建Polars Date标量 startdate = pl.Date(year=2023, month=1, day=1) enddate = pl.Date(year=2023, month=1, day=10) frequency = pl.Duration(days=1) i = 0 while startdate <= enddate: print(i) i += 1 startdate += frequency
带时间的日期类型(Datetime)示例代码
import polars as pl # 创建Polars Datetime标量 startdate = pl.Datetime(year=2023, month=1, day=1) enddate = pl.Datetime(year=2023, month=1, day=10) frequency = pl.Duration(days=1) i = 0 while startdate <= enddate: print(i) i += 1 startdate += frequency
方式2:从字符串解析标量
如果日期是字符串格式,可直接用parse方法解析为Polars标量:
startdate = pl.Date.parse("2023-01-01") enddate = pl.Date.parse("2023-01-10")
方式3:从Python datetime对象转换
若已有Python的datetime.date或datetime.datetime对象,可直接传入Polars的标量构造函数:
import datetime # 从Python date对象转换为Polars Date标量 startdate = pl.Date(datetime.date(2023, 1, 1)) # 从Python datetime对象转换为Polars Datetime标量 startdate = pl.Datetime(datetime.datetime(2023, 1, 1, 12, 0, 0))
循环内适配Polars表达式使用
如果需要在循环内将日期标量用于is_between()等Polars表达式操作,直接传入标量即可,Polars会自动适配表达式上下文:
import polars as pl # 示例DataFrame df = pl.DataFrame({ "date": pl.date_range(start="2023-01-01", end="2023-01-15", interval="1d") }) startdate = pl.Date(year=2023, month=1, day=1) enddate = pl.Date(year=2023, month=1, day=10) frequency = pl.Duration(days=1) i = 0 while startdate <= enddate: # 使用当前startdate作为过滤条件 filtered_df = df.filter(pl.col("date").is_between(startdate, startdate)) print(f"第{i}天数据:\n{filtered_df}") i += 1 startdate += frequency
内容的提问来源于stack exchange,提问作者Balthazar
相关产品推荐
相关产品推荐

