跳到主要內容

Rust - Polars 資料欄位型態轉換,從 str 變 Date

緣起

Polars 是一個以 Rust 語言開發的 「DataFrame」 新興套件,它可以同時在 Rust 及 Python 中使用。Polars 憑藉著 Rust 的執行速度為基礎,讓它在資料處理的領域中, 逐漸流行起來。

但正由於它還在發展初期,目前網路上的參考文章相對較少,中文的內容更是稀有;所以整理了一下這週末的一些研究心得,一來避免自己忘記,二來也在網路上與大家分享,希望慢慢的能讓 Rust 的中文資源可以越來越完整,有朝一日可以在華人世界中流行起來。


本文開始

本週研究的主題是 Polars 裡,對「DataFrame」某個「str」欄位,進行資料型別轉換為「Date」或「Datetime」。資料的轉換可以有多種方式,應該不只限於接下來提到的方法。


建立第一個資料集

為了開始這個操作,我們需要先建立起一個「DataFrame」。


let date = Series::new("trans_date", &[
"2023-05-01",
"2023-05-02",
"2023-05-03",
"2023-05-04",
"2023-05-05",
]);

let df = DataFrame::new(vec![ date ]);
println!("{}", df.clone().collect()?);
 

執行後, 可以看到以下的結果:

 shape: (5, 1)
┌────────────┐
│ trans_date │
│ ---        │
│ str        │
╞════════════╡
│ 2023-05-01 │
│ 2023-05-02 │
│ 2023-05-03 │
│ 2023-05-04 │
│ 2023-05-05 │
└────────────┘

從執行的結果中,我們可以清楚的看到,目前所建立的「DataFrame」,在「trans_date」的欄位中,它的資料型態為「str」;也就是說,目前它是一個字串。如果我們只有操作到這裡,我想這樣的結果還不致於會有什麼太大的問題,反正只是把結果給顯示出來,頂多做個排序,大致上結果應該都會是正確的。

但如果我們想做的不只是這樣,需要對這個資料集進行一些更細緻的操作呢(例如,對這個資料進行過濾,找出早於/晚於某個日期的記錄)?這個時候,將原本的「str」型態轉換為「Date」型態,相信會是一個更好的選擇。


準備進行轉換

在開始進行轉換之前,我們要對上面的程式碼做一點小小的調整。Polars 的「DataFrame」操作模式有兩種,一為一般模式,二為「Lazy」模式。兩者最大的差別在於,一般模式在每一個功能呼叫時,當下就會對資料集進行操作;但「Lazy」模式則是在最終確認後,才一次執行所有的運算。「Lazy」模式讓我想到多年前學習 Big Data 時,使用 Apache Hadoop 及 Apache Spark,以及這幾年玩機器學習框架 TensorFlow 及 PyTorch 時,對資料集進行操作的方式,實在有異曲同工之妙。

在 Polars 官方的說明文件中,推薦我們使用「Lazy」模式,因此對程式做一些小小的調整:


let date = Series::new("trans_date", &[
"2023-05-01",
"2023-05-02",
"2023-05-03",
"2023-05-04",
"2023-05-05",
]);

let df = DataFrame::new(vec![ date ])?.lazy();

在上面的程式碼裡,紅色的「 .lazy() 」幫我們把原本的「DataFrame」,轉換為「LazyFrame」。在轉換操作模式後,我們透過下面的操作,要開始對資料集的「trans_date」欄,進行型別轉換:


// casting data type
let df = df.with_column(
col("trans_date").str().strptime(
DataType::Date,
StrptimeOptions {
format: Some("%Y/%m/%d".into()),
cache: false,
exact: false,
strict: false,
tz_aware: false,
utc: false,
},
)
);
 
println!("{}", df.clone().collect()?); 

「.with_column()」 用來為一個「DataFrame」加入一個欄位;過程裡,我們可以透過 Polars 裡的 Expression 描述,來對某一個欄位進行運算操作,並將結果存入這個欄位中。有一點比較特別的是,如果沒有特別再定義別名(alias),則運算後的結果,將會回填到原本指定的欄位中(在我們的例子裡,會寫入 「trans_date」 欄位)。我們即利用這個行為, 來為資料集的特定欄位,進行資料型別的轉換。

執行後,印出資料集的內容如下:

shape: (5, 1)
┌────────────┐
│ trans_date │
│ ---        │
│ date       │
╞════════════╡
│ 2023-05-01 │
│ 2023-05-02 │
│ 2023-05-03 │
│ 2023-05-04 │
│ 2023-05-05 │
└────────────┘

到這裡,我們可以清楚看到欄位的資料型態,已經從原本的「str」變更為「date」。

以下附上完整的程式碼:  

 
use polars::prelude::*;

fn main() -> PolarsResult<()> {
let date = Series::new(
"trans_date",
&[
"2023-05-01",
"2023-05-02",
"2023-05-03",
"2023-05-04",
"2023-05-05",
],
);

let price = Series::new("price", &[1, 2, 3, 4, 5]);

let df = DataFrame::new(vec![date])?.lazy();

// casting data type
let df = df.with_column(
col("trans_date").str().strptime(
DataType::Date,
StrptimeOptions {
format: Some("%Y-%m-%d".into()),
cache: false,
exact: false,
strict: false,
tz_aware: false,
utc: false,
},
));

println!("{}", df.clone().collect()?);

Ok(())
}

 


留言

這個網誌中的熱門文章

聯合報招待所─南園(一)

06/02是攝影班的第三次外拍,一早八點就到學校集合。那些可愛的阿伯同學還是一如往常,早早就在遊覽車上等我們了。網路上看南園的相關介紹,就覺得那裡的景色很漂亮,蠻期待今天的外拍。 本來說要帶甜姐兒米粒一塊去的,誰知道這隻懶鬼竟然裝龜不來了,害的一位滿懷期待,想要好好幫米粒拍照的同學落了個空,難過死啦!米粒,妳要負責。 一到了南園就覺得美麗的風景映入眼簾;可是我們在十點多到達,天氣正好,陽光也大,結果怎麼拍都是天空跟景物反差太大,動不動就爆掉。而且天氣熱,又爬上爬下的,搞的我滿身汗;反正光線不滿意,天氣熱、人又懶,干脆到處晃晃準備吃午飯。 太陽一直都很大。本來吃過午飯後,打算找個樹蔭好好的給它睡個午覺,等光線柔合一點再動。誰知道大家幹勁十足,一直嚷嚷著要去拍照了!唉,年輕人還是不要太懶,只好硬著頭皮跟著走。忘了帶腳架,相機拿不穩,只好拍些光線亮的;可是光線亮的又容易爆 :P 天啊!這不是存心搞我嗎?還好將近三點的時候,光線慢慢的開始柔合了下來,也有一些斜光。由於天氣很好,加上濾鏡的關係,所以看起來天空特別的藍;不多說,趕快拿起就是一陣猛拍嚕! 這次拍的照片還不少,而且品質好壞差很多,挑這些照片真是一種考驗。所以我先把部份處理好的,先貼上來分享,剩下的再另外貼一篇嚕! Fig1. 參觀由此進... Fig2. 餐廳前花圃 Fig3. 老師講評:紅色磚牆的部份,有點過曝、細節不明顯。 Fig4. 南樓一角(老師,我還是覺得你那張拍的好...) 老師講評:屋簷再突出一些到天空,整個構的的感覺會更好。 Fig5. Fig6. 這個景我看好多人也有拍耶... Fig7. 晴空下的沙漠玫瑰 Fig8. Fig9. 老師講評:如果可以把紅面的磚牆保留一些下來,整體的感覺會更棒。

PROJECT 365, #036

PROJECT 365, #036 Originally uploaded by PRLiu Master Wu is a cultural relic protector, and is also a rubbing master. It is my rest day. I pick my camera up, and take the metro to Long-Shan Temple. I would like to have something special. Fortunately, I meet Master Wu, who shows me the traditional cultural. Thank you. Visit Master Wu's website. www.lyu.org.tw Information: Camera: Nikon D90 Lens: Tokina AT-X 124 12-24mm/f4 Location: Long-Shan Temple

衝到四道好浪,爽!

距離上次作品發表的時間,已剛好整整一個月。這一個月裡,都在忙些雜事,也就沒了新作品的發表。 星期天趁著萬宜颱風的外圍環流還在,趕緊跑到金山試試身手。雖然整體的浪況很不理想,不過在下午三點半的時候,浪突然變的穩定下來,讓我迫不急待的下水一試。沒想到好浪連連,一連搭了四道回來;不過也因為起浪點都在 Outside,距離遠,相當耗體力,衝完了這四道也就差不多了。 想著時間慢慢的變晚,浪況也逐漸轉壞,甘脆收拾板子回家,也好早點吃飯。沒想到就在回家的路上,看到了永福橋旁的晚霞,決定了大致的構圖,二話不說的馬上衝回家拿相機,留下了這幾張作品。 #1. 以河岸旁的大樓做剪影;雲層、晚霞、大樓成三等分分配。 #2. #3. 拿樹當剪影;不過樹延伸的方向有點怪。