Polars Rust中迭代DateChunked时如何获取日期类型元素
问题描述
在使用Rust版本Polars库时,通过map方法迭代DateChunked类型时,迭代返回的元素是i32类型,无法直接作为日期类型使用,运行如下示例代码时触发编译错误:
use polars::export::chrono::{NaiveDate}; fn main() { let df = df! [ "date_series" => [NaiveDate::from_ymd(2020, 1, 1), NaiveDate::from_ymd(2020, 1, 2), NaiveDate::from_ymd(2020, 1, 3)] ].unwrap(); let a: DateChunked = df["date_series"].date().unwrap().into_iter().map(|d| { match d { Some(d) => Some(d), None => None } }).collect(); }
对应编译报错:
}).collect(); | ^^^^^^^ value of type `Logical<DateType, Int32Type>` cannot be built from `std::iter::Iterator<Item=Option<i32>>`
报错原因
DateChunked的本质是Polars的逻辑日期类型,底层物理存储格式是i32,数值代表距离1970-01-01的天数。直接调用into_iter()迭代时,拿到的是底层存储的Option<i32>物理值,不是封装后的NaiveDate日期对象,迭代器的元素类型和DateChunked要求的收集类型不匹配,因此触发编译错误。
解决方法
根据使用场景选择对应写法即可:
- 如果只需要在迭代过程中拿到
NaiveDate类型做自定义计算,不需要收集回DateChunked,调用as_date_iter()方法生成日期迭代器,该迭代器返回的元素直接是Option<NaiveDate>类型,无需手动转换。 - 如果需要对日期做转换后重新收集为
DateChunked,同样使用as_date_iter()拿到NaiveDate做处理,处理完成后直接通过into()方法将存放Option<NaiveDate>的可信长度集合转换为DateChunked即可。
正确可运行的示例代码如下:
use polars::prelude::*; use polars::export::chrono::{NaiveDate, Duration}; fn main() -> PolarsResult<()> { let df = df! [ "date_series" => [ NaiveDate::from_ymd_opt(2020, 1, 1).unwrap(), NaiveDate::from_ymd_opt(2020, 1, 2).unwrap(), NaiveDate::from_ymd_opt(2020, 1, 3).unwrap() ] ]?; let date_col = df["date_series"].date()?; // 场景1:直接迭代拿到NaiveDate做逻辑处理 for opt_date in date_col.as_date_iter() { match opt_date { Some(d) => println!("读取到日期:{}", d), None => println!("当前位置为空值") } } // 场景2:处理后收集回DateChunked,示例为所有日期+1天 let new_date_col: DateChunked = date_col .as_date_iter() .map(|opt_d| opt_d.map(|d| d + Duration::days(1))) .collect_trusted::<Vec<_>>() .into(); dbg!(new_date_col); Ok(()) }
注:新版本Polars中
NaiveDate::from_ymd方法已标记为废弃,替换为返回Option的from_ymd_opt方法,调用后做unwrap()处理即可。
内容的提问来源于stack exchange,提问作者Kushdesh
相关产品推荐
相关产品推荐

