手把手教你學Numpy,搞定數據處理——收官篇

手把手教你學Numpy,搞定數據處理——收官篇

本文始發於個人公眾號:TechFlow,原創不易,求個關注

今天是Numpy專題第6篇文章,我們一起來看看Numpy庫當中剩餘的部分。

數組的持久化

在我們做機器學習模型的研究或者是學習的時候,在完成了訓練之後,有時候會希望能夠將相應的參數保存下來。否則的話,如果是在Notebook當中,當Notebook關閉的時候,這些值就丟失了。一般的解決方案是將我們需要的值或者是數組“持久化”,通常的做法是存儲在磁盤上。

Python當中讀寫文件稍稍有些麻煩,我們還需要創建文件句柄,然後一行行寫入,寫入完成之後需要關閉句柄。即使是用with語句,也依然不夠簡便。針對這個問題,numpy當中自帶了寫入文件的api,我們直接調用即可。

通過numpy當中save的文件是二進制格式的,所以我們是無法讀取其中內容的,即使強行打開也會是亂碼。

以二進制的形式存儲數據避免了數據類型轉化的過程,尤其是numpy底層的數據是以C++實現的,如果使用Python的文件接口的話,勢必要先轉化成Python的格式,這會帶來大量開銷。既然可以存儲,自然也可以讀取,我們可以調用numpy的load函數將numpy文件讀取進來。

要注意我們保存的時候沒有添加文件後綴,numpy會自動為我們添加後綴,但是讀取的時候必須要指定文件的全名,否則會numpy無法找到,會引發報錯。

不僅如此,numpy還支持我們同時保存多個數組進入一個文件當中。

我們使用savez來完成,在這個api當中我們傳入了a=arr,b=arr,其實是以類似字典的形式傳入的。在文件當中,numpy會將變量名和數組的值映射起來。這樣我們在讀入的時候,就可以通過變量名訪問到對應的值了。

如果要存儲的數據非常大的話,我們還可以對數據進行壓縮,我們只需要更換savez成savez_compressed即可。

線性代數

Numpy除了科學計算之外,另外一大強大的功能就是支持矩陣運算,這也是它廣為流行並且在機器學習當中大受歡迎的原因之一。我們在之前的線性代數的文章當中曾經提到過Numpy這方面的一些應用,我們今天再在這篇文章當中匯總一些常用的線性代數的接口。

點乘

說起來矩陣點乘應該是最常用的線代api了,比如在神經網絡當中,如果拋開激活函數的話,一層神經元對於當前數據的影響,其實等價於特徵矩陣點乘了一個係數矩陣。再比如在邏輯回歸當中,我們計算樣本的加權和的時候,也是通過矩陣點乘來實現的。

在Andrew的深度學習課上,他曾經做過這樣的實現,對於兩個巨大的矩陣進行矩陣相乘的運算。一次是通過Python的循環來實現,一次是通過Numpy的dot函數實現,兩者的時間開銷相差了足足上百倍。這當中的效率差距和Python語言的特性以及併發能力有關,所以在機器學習領域當中,我們總是將樣本向量化或者矩陣化,通過點乘來計算加權求和,或者是係數相乘。

在Numpy當中我們採用dot函數來計算兩個矩陣的點積,既可以寫成a.dot(b),也可以寫成np.dot(a, b)。一般來說我更加喜歡前者,因為寫起來更加方便清晰。如果你喜歡後者也問題不大,這個只是個人喜好。

注意不要寫成*,這個符號代表兩個矩陣元素兩兩相乘,而不是進行點積運算。它等價於np當中的multiply函數。

轉置與逆矩陣

轉置我們曾經在之前的文章當中提到過,可以通過.T或者是np.transpose來完成。

Numpy中還提供了求解逆矩陣的操作,這個函數在numpy的linalg路徑下,這個路徑下實現了許多常用的線性代數函數。根據線性代數當中的知識,只有滿秩的方陣才有逆矩陣。我們可以通過numpy.linalg.det先來計算行列式來判斷,否則如果直接調用的話,對於沒有逆矩陣的矩陣會報錯。

在這個例子當中,由於矩陣b的行列式為0,說明它並不是滿秩的,所以我們求它的逆矩陣會報錯。

除了這些函數之外,linalg當中還封裝了其他一些常用的函數。比如進行qr分解的qr函數,進行奇異值分解的svd函數,求解線性方程組的solve函數等。相比之下,這些函數的使用頻率相對不高,所以就不展開一一介紹了,我們可以用到的時候再去詳細研究。

隨機

Numpy當中另外一個常用的領域就是隨機數,我們經常使用Numpy來生成各種各樣的隨機數。這一塊在Numpy當中其實也有很多的api以及很複雜的用法,同樣,我們不過多深入,挑其中比較重要也是經常使用的和大家分享一下。

隨機數的所有函數都在numpy.random這個路徑下,我們為了簡化,就不寫完整的路徑了,大家記住就好。

randn

這個函數我們經常在代碼當中看到,尤其是我們造數據的時候。它代表的是根據輸入的shape生成一批均值為0,標準差為1的正態分佈的隨機數。

要注意的是,我們傳入的shape不是一個元組,而是每一維的大小,這一點和其他地方的用法不太一樣,需要注意一下。除了正態分佈的randn之外,還有均勻分佈的uniform和Gamma分佈的gamma,卡方分佈的chisquare。

normal

normal其實也是生成正態分佈的樣本值,但不同的是,它支持我們指定樣本的均值和標準差。如果我們想要生成多個樣本,還可以在size參數當中傳入指定的shape。

randint

顧名思義,這個函數是用來生成隨機整數的。它接受傳入隨機數的上下界,最少也要傳入一個上界(默認下界是0)。

如果想要生成多個int,我們可以在size參數傳入一個shape,它會返回一個對應大小的數組,這一點和uniform用法一樣。

shuffle

shuffle的功能是對一個數組進行亂序,返回亂序之後的結果。一般用在機器學習當中,如果存在樣本聚集的情況,我們一般會使用shuffle進行亂序,避免模型受到樣本分佈的影響。

shuffle是一個inplace的方法,它會在原本值上進行改動,而不會返回一個新值。

choice

這也是一個非常常用的api,它可以在數據當中抽取指定條數據。

但是它只支持一維的數組,一般用在批量訓練的時候,我們通過choice採樣出樣本的下標,再通過數組索引去找到這些樣本的值。比如這樣:

總結

今天我們一起研究了Numpy中數據持久化、線性代數、隨機數相關api的使用方法,由於篇幅的限制,我們只是選擇了其中比較常用,或者是比較重要的用法,還存在一些較為冷門的api和用法,大家感興趣的可以自行研究一下,一般來說文章當中提到的用法已經足夠了。

今天這篇是Numpy專題的最後一篇了,如果你堅持看完本專題所有的文章,那麼相信你對於Numpy包一定有了一個深入的理解和認識了,給自己鼓鼓掌吧。之後周四會開啟Pandas專題,敬請期待哦。

如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

本文使用 mdnice 排版

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!