本文始發於我的公衆號:TechFlow,原創不易,求個關注web
今天是Numpy專題第6篇文章,咱們一塊兒來看看Numpy庫當中剩餘的部分。api
在咱們作機器學習模型的研究或者是學習的時候,在完成了訓練以後,有時候會但願可以將相應的參數保存下來。不然的話,若是是在Notebook當中,當Notebook關閉的時候,這些值就丟失了。通常的解決方案是將咱們須要的值或者是數組「持久化」,一般的作法是存儲在磁盤上。數組
Python當中讀寫文件稍稍有些麻煩,咱們還須要建立文件句柄,而後一行行寫入,寫入完成以後須要關閉句柄。即便是用with語句,也依然不夠簡便。針對這個問題,numpy當中自帶了寫入文件的api,咱們直接調用便可。網絡
經過numpy當中save的文件是二進制格式的,因此咱們是沒法讀取其中內容的,即便強行打開也會是亂碼。併發
以二進制的形式存儲數據避免了數據類型轉化的過程,尤爲是numpy底層的數據是以C++實現的,若是使用Python的文件接口的話,勢必要先轉化成Python的格式,這會帶來大量開銷。既然能夠存儲,天然也能夠讀取,咱們能夠調用numpy的load函數將numpy文件讀取進來。dom
要注意咱們保存的時候沒有添加文件後綴,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這個路徑下,咱們爲了簡化,就不寫完整的路徑了,你們記住就好。
這個函數咱們常常在代碼當中看到,尤爲是咱們造數據的時候。它表明的是根據輸入的shape生成一批均值爲0,標準差爲1的正態分佈的隨機數。
要注意的是,咱們傳入的shape不是一個元組,而是每一維的大小,這一點和其餘地方的用法不太同樣,須要注意一下。除了正態分佈的randn以外,還有均勻分佈的uniform和Gamma分佈的gamma,卡方分佈的chisquare。
normal其實也是生成正態分佈的樣本值,但不一樣的是,它支持咱們指定樣本的均值和標準差。若是咱們想要生成多個樣本,還能夠在size參數當中傳入指定的shape。
顧名思義,這個函數是用來生成隨機整數的。它接受傳入隨機數的上下界,最少也要傳入一個上界(默認下界是0)。
若是想要生成多個int,咱們能夠在size參數傳入一個shape,它會返回一個對應大小的數組,這一點和uniform用法同樣。
shuffle的功能是對一個數組進行亂序,返回亂序以後的結果。通常用在機器學習當中,若是存在樣本彙集的狀況,咱們通常會使用shuffle進行亂序,避免模型受到樣本分佈的影響。
shuffle是一個inplace的方法,它會在本來值上進行改動,而不會返回一個新值。
這也是一個很是經常使用的api,它能夠在數據當中抽取指定條數據。
可是它只支持一維的數組,通常用在批量訓練的時候,咱們經過choice採樣出樣本的下標,再經過數組索引去找到這些樣本的值。好比這樣:
今天咱們一塊兒研究了Numpy中數據持久化、線性代數、隨機數相關api的使用方法,因爲篇幅的限制,咱們只是選擇了其中比較經常使用,或者是比較重要的用法,還存在一些較爲冷門的api和用法,你們感興趣的能夠自行研究一下,通常來講文章當中提到的用法已經足夠了。
今天這篇是Numpy專題的最後一篇了,若是你堅持看完本專題全部的文章,那麼相信你對於Numpy包必定有了一個深刻的理解和認識了,給本身鼓鼓掌吧。以後週四會開啓Pandas專題,敬請期待哦。
若是喜歡本文,能夠的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。
本文使用 mdnice 排版