簡介
大家(好的,其實是大多數人)都說 Rust 很難,但我不這么認為。雖然 Rust 可能比 Python 稍微難一些,但我們可以像學習 Python 一樣學習 Rust - 通過使用 Jupyter。
在本文中,我將向你展示如何以交互模式編寫 Rust 代碼,特別是在數據科學場景中。
安裝
首先,你需要安裝 Python 開發的交互式筆記本 Jupyter。你可以通過以下方式安裝(我假設你之前已經安裝了 Python):
pipinstalljupyterlab
請記得檢查安裝是否成功,請運行以下命令:
jupyterlab
你將會看到一個 Web 用戶界面,請立即關閉它。之后,我們需要安裝 Evcxr Jupyter Kernel,它是 Jupyter 的 Rust 內核擴展。你可以通過以下方式安裝(我假設你之前已經在計算機上安裝了 Rust):
cargoinstall--lockedevcxr_jupyter
evcxr_jupyter--install
之后,再次啟動 Jupyter UI,你將看到類似于以下內容:
恭喜,我們在啟動器面板上看到了 Rust 的標志。
只需單擊 Notebook 部分下的 Rust 方塊,我們就可以得到:
一切準備就緒,我們開始吧!
基本操作
為了練習本教程,我建議你具備 Rust 語言的基本背景。讓我們從測試基本變量綁定開始,
輸出:
輸出會在 Rust 代碼下一行打印,是的,是交互式的。
讓我們繼續。
看起來一切都很順利。我們現在可以繼續進行更復雜的任務。
我們將利用三個數據科學工具:polars、ndarray 和 plotters,學習如何使用 Rust 進行數據分析。
使用Polars分析數據集
在本教程中,我將選擇泰坦尼克號數據集作為示例,以說明 Rust 的便利性。
根據 Bing 的說法:“泰坦尼克號數據集是用于數據科學和機器學習的流行數據集。它包含有關泰坦尼克號上的乘客的信息,包括年齡、性別、等級、票價以及他們是否在災難中幸存。這個數據集經常用于預測建模練習,例如根據乘客的特征預測乘客是否能夠幸存。這是一個適合數據分析和機器學習初學者的經典數據集,廣泛用于 Kaggle 競賽。”
我們可以從這里(https://huggingface.co/datasets/phihung/titanic)下載泰坦尼克號數據集,并將其移動到 dataset/ 子目錄中。
添加依賴:
:depndarray={version="0.15.6"}
:deppolars={version="0.35.4",features=["describe","lazy","ndarray"]}
:depplotters={version="0.3.5",default_features=false,features=["evcxr","all_series","all_elements"]}
顯示依賴:
:show_deps
輸出:
ndarray={version="0.15.6"}
plotters={version="0.3.5",default_features=false,features=["evcxr","all_series","all_elements"]}
polars={version="0.35.4",features=["describe","lazy","ndarray"]}
將數據集讀入 polars 內存:
usepolars::*;
usepolars::DataFrame;
usestd::Path;
fnread_data_frame_from_csv(
csv_file_path:&Path,
)->DataFrame{
CsvReader::from_path(csv_file_path)
.expect("Cannotopenfile.")
.has_header(true)
.finish()
.unwrap()
}
lettitanic_file_path:&Path=Path::new("dataset/titanic.csv");
lettitanic_df:DataFrame=read_data_frame_from_csv(titanic_file_path);
查看數據的形狀:
titanic_df.shape()
輸出:
(891,12)
DataFrame 是 polars 中的基本結構,與 Python Pandas 中的 DataFrame 相同,你可以將其視為具有每列命名標題的二維數據表格。
以下是查看數據集基本統計信息的代碼示例:
titanic_df.describe(None)
輸出:
我們可以看到這個數據集中有一些空單元格。
以下是查看數據集前 5 行的代碼示例:
titanic_df.head(Some(5))
輸出:
如果你想查看數據集中的列名,請使用 .schema() 方法。以下是代碼示例:
titanic_df.schema()
輸出:
Schema:
name:PassengerId,datatype:Int64
name:Survived,datatype:Int64
name:Pclass,datatype:Int64
name:Name,datatype:String
name:Sex,datatype:String
name:Age,datatype:Float64
name:SibSp,datatype:Int64
name:Parch,datatype:Int64
name:Ticket,datatype:String
name:Fare,datatype:Float64
name:Cabin,datatype:String
name:Embarked,datatype:String
使用以下代碼來查看泰坦尼克號數據集中幸存者:
titanic_df["Survived"].value_counts(true,true)
輸出:
Ok(shape:(2,2)
┌──────────┬───────┐
│Survived┆count│
│---┆---│
│i64┆u32│
╞══════════╪═══════╡
│0┆549│
│1┆342│
└──────────┴───────┘)
查看泰坦尼克號數據集中的性別分布:
titanic_df["Sex"].value_counts(true,true)
輸出:
Ok(shape:(2,2)
┌────────┬────────┐
│Sex┆counts│
│---┆---│
│str┆u32│
╞════════╪════════╡
│male┆577│
│female┆314│
└────────┴────────┘)
你可以在 titanic_df DataFrame 上繼續進行更復雜的 EDA(探索性數據分析)。
使用Plotters對數據可視化
接下來,我們可以使用 plotters crate 來可視化我們的輸出數據。以下是導入 plotters crate 的符號:
useplotters::*;
畫一個柱狀圖:
evcxr_figure((640,480),|root|{
letdrawing_area=root;
drawing_area.fill(&WHITE).unwrap();
letmutchart_context=ChartBuilder::on(&drawing_area)
.caption("TitanicDataset",("Arial",30).into_font())
.x_label_area_size(40)
.y_label_area_size(40)
.build_cartesian_2d((0..1).into_segmented(),0..800)?;
chart_context.configure_mesh()
.x_desc("Survived?")
.y_desc("Number").draw()?;
letdata_s:DataFrame=titanic_df["Survived"].value_counts(true,true).unwrap().select(vec!["counts"]).unwrap();
letmutdata_source=data_s.to_ndarray::(IndexOrder::Fortran).unwrap().into_raw_vec().into_iter();
chart_context.draw_series((0..).zip(data_source).map(|(x,y)|{
letx0=SegmentValue::Exact(x);
letx1=SegmentValue::Exact(x+1);
letmutbar=Rectangle::new([(x0,0),(x1,y)],BLUE.filled());
bar.set_margin(0,0,30,30);
bar
}))
.unwrap();
Ok(())
}).style("width:60%")
顯示:
這段代碼看起來有些冗長和繁瑣,以后最好在 plotters 中封裝一個簡單的 API 。現在的核心問題是 1. 配置項過多,2. 類型轉換復雜。
Plotters 支持各種圖形、繪圖和圖表,你可以將 plotters 視為 Rust 生態系統中 Python matplotlib 的對應物,但它要趕上 matplotlib 的易用性,還有不小的差距。
有關 plotters 的更多信息,請訪問:https://docs.rs/plotters/latest/plotters/
接下來,我們將介紹矩陣操作庫 ndarray。
使用Ndarray操作矩陣
DataFrame 有一個方法可以將自身轉換為 Ndarray 的多維矩陣。例如:
leta=UInt32Chunked::new("a",&[1,2,3]).into_series();
letb=Float64Chunked::new("b",&[10.,8.,6.]).into_series();
letdf=DataFrame::new(vec![a,b]).unwrap();
letndarray=df.to_ndarray::(IndexOrder::Fortran).unwrap();
println!("{:?}",ndarray);
將輸出:
[[1.0,10.0],
[2.0,8.0],
[3.0,6.0]],shape=[3,2],strides=[1,3],layout=Ff(0xa),constndim=2
我們可以使用 ndarray crate 來進行復雜的矩陣操作。
導入 ndarray crate 的符號:
usendarray::*;
創建一個 2x3 矩陣:
array![[1.,2.,3.],[4.,5.,6.]]
輸出:
[[1.0,2.0,3.0],
[4.0,5.0,6.0]],shape=[2,3],strides=[3,1],layout=Cc(0x5),constndim=2
創建一個范圍:
Array::range(0.,10.,0.5)
輸出:
[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5],shape=[20],strides=[1],layout=CFcf(0xf),constndim=1
創建一個具有指定相等間隔的范圍:
Array::linspace(0.,10.,18)
輸出:
[0.0,0.5882352941176471,1.1764705882352942,1.7647058823529411,2.3529411764705883,2.9411764705882355,3.5294117647058822,4.11764705882353,4.705882352941177,5.294117647058823,5.882352941176471,6.470588235294118,7.0588235294117645,7.647058823529412,8.23529411764706,8.823529411764707,9.411764705882353,10.0],shape=[18],strides=[1],layout=CFcf(0xf),constndim=1
以下是創建一個 3x4x5 矩陣(也稱為機器學習中的“張量”)的代碼示例:
Array::::ones((3,4,5))
輸出:
[[[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0]],
[[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0]],
[[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0],
[1.0,1.0,1.0,1.0,1.0]]],shape=[3,4,5],strides=[20,5,1],layout=Cc(0x5),constndim=3
以下是創建一個零值初始矩陣的代碼示例:
Array::::zeros((3,4,5))
輸出:
[[[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0]],
[[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0]],
[[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0],
[0.0,0.0,0.0,0.0,0.0]]],shape=[3,4,5],strides=[20,5,1],layout=Cc(0x5),constndim=3
對行和列求和
letarr=array![[1.,2.,3.],[4.,5.,6.]];
按行求和
arr.sum_axis(Axis(0))
輸出:
[5.0,7.0,9.0],shape=[3],strides=[1],layout=CFcf(0xf),constndim=1
按列求和:
arr.sum_axis(Axis(1))
輸出:
[6.0,15.0],shape=[2],strides=[1],layout=CFcf(0xf),constndim=1
所有元素求和:
arr.sum()
輸出:
21.0
矩陣轉置:
arr.t()
輸出:
[[1.0,4.0],
[2.0,5.0],
[3.0,6.0]],shape=[3,2],strides=[1,3],layout=Ff(0xa),constndim=2
求點積:
arr.dot(&arr.t())
輸出:
[[14.0,32.0],
[32.0,77.0]],shape=[2,2],strides=[2,1],layout=Cc(0x5),constndim=2
求方根:
arr.mapv(f64::sqrt)
輸出:
[[1.0,1.4142135623730951,1.7320508075688772],
[2.0,2.23606797749979,2.449489742783178]],shape=[2,3],strides=[3,1],layout=Cc(0x5),constndim=2
矩陣操作暫時演示到這里。ndarray 是一個非常強大的工具,你可以使用它來執行與矩陣和線性代數相關的任何任務。
回顧
在本文中,我演示了如何使用 Jupyter 交互式地學習 Rust。Jupyter 是數據科學家(或學生)的超級工具,我們現在可以使用 Rust 在 Jupyter 中完成探索性數據分析任務。Polars、plotters 和 ndarray 是強大的工具集,可以幫助我們處理數據分析和數據預處理工作,這是后續機器學習任務的先決條件。
-
機器學習
+關注
關注
66文章
8420瀏覽量
132685 -
數據集
+關注
關注
4文章
1208瀏覽量
24713 -
Rust
+關注
關注
1文章
229瀏覽量
6614
原文標題:【Rust AI】01. 使用Jupyter學習Rust
文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論