如何在Rust的Polars DataFrame中用i64向量创建Datetime列?
在Rust Polars中用i64时间戳构建Datetime列(高性能方案)
要让df!宏将i64时间戳向量识别为Datetime类型,核心是显式指定列的数据类型,同时要保证内存复用、最小化分配。以下是两种最优方案:
方案一:直接构造Datetime Series(性能最优)
这种方式直接接管原i64向量的内存,无额外复制,是性能最好的选择:
use polars::prelude::*; use chrono::Utc; fn main() { // 生成毫秒级时间戳向量 let mut datetime_vec: Vec<i64> = Vec::new(); datetime_vec.push(Utc::now().timestamp_millis()); datetime_vec.push(Utc::now().timestamp_millis() + 3600 * 1000); // 加1小时 // 直接用原向量构造Datetime类型的Series let datetime_series = Series::new_with_dtype( "datetime_col", datetime_vec, &DataType::Datetime(TimeUnit::Milliseconds, None) ).expect("Failed to create datetime series"); // 传入df!宏构建DataFrame let df = df![datetime_series].expect("Failed to create DataFrame"); // 验证类型 println!("Schema: {:?}", df.schema()); println!("Data:\n{}", df); }
关键细节:
Series::new_with_dtype会直接复用传入的Vec<i64>内存,无需额外分配。- 必须匹配时间戳的单位:这里用
timestamp_millis(),所以指定TimeUnit::Milliseconds,如果是秒级时间戳则用TimeUnit::Seconds。
方案二:在df!宏内直接转换
如果希望在宏内完成类型转换,可以用cast方法,但注意这种方式会产生一次内存复制(因为cast需要重新构造数据):
use polars::prelude::*; use chrono::Utc; fn main() { let mut datetime_vec: Vec<i64> = Vec::new(); datetime_vec.push(Utc::now().timestamp_millis()); datetime_vec.push(Utc::now().timestamp_millis() + 3600 * 1000); let df = df!( "datetime_col" => datetime_vec.into_series() .cast(&DataType::Datetime(TimeUnit::Milliseconds, None)) .expect("Failed to cast to datetime") ).expect("Failed to create DataFrame"); println!("Schema: {:?}", df.schema()); }
避坑提示
- 不要依赖自动类型推断:i64向量默认会被解析为
Int64列,必须显式指定Datetime类型。 - 时间单位必须严格匹配:如果时间戳是毫秒级但用了
Seconds,会导致时间显示为1970年附近的错误值。
内容的提问来源于stack exchange,提问作者deepvalue
相关产品推荐
相关产品推荐

