Python進階之NumPy快速入門(三)
- 2019 年 10 月 11 日
- 筆記
引言
NumPy是Python的一個擴展庫,負責數組和矩陣運行。相較於傳統Python,NumPy運行效率高,速度快,是利用Python處理數據必不可少的工具。
這個NumPy快速入門系列分為四篇,包含了NumPy大部分基礎知識,每篇閱讀時間不長,但內容含量高。大家最好親自碼一遍代碼,這樣可以更有收穫。
前面課程:
概要
1、掌握NumPy中的數組操作,輕鬆改變數組形狀;
2、掌握NumPy中的字符串,輕鬆應對文件處理;
3、掌握Python中的統計函數,輕鬆進行統計分析。
數組操作
我們將數組操作分成以下幾種類型,然後分別介紹
- 數組變形
- 數組翻轉
- 數組連接
- 數組分割
數組變形
可以實現數組變形的函數有好幾個:
- reshape,最常見的也是最主要的數組變形函數。可以將數組從一個形狀轉變成另外一個不同的形狀。
- flatten,可以將高維數組展開成一維。先建好一個數組A,然後輸出A.flatten()就可以完成降維。當然,我們可以選擇展開式的秩序order。如果order='F',就是按列展開;如果order='C',就是按行展開。
- ravel,它和flatten功能其實差不多,可以將高維數組展開成一維。而且默認的展開順序也是order='C',即按行展開。如果選擇order='F'就是按列展開。
代碼:
import numpy as np A = np.arange(0,12) B = A.reshape(2,6) C = B.flatten(order='F') D = B.ravel() print (A, 'n', B, 'n', C, 'n', D)
講解:
原始數組A是一個從0到11的一維數組;B是通過reshape函數改造成2*6的二維數組;C和D分別從B展開降到一維。其中C是按列順序降維,而D是按照行順序。
運行結果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
[ 0 6 1 7 2 8 3 9 4 10 5 11]
[ 0 1 2 3 4 5 6 7 8 9 10 11]
數組翻轉
從數學角度而言,二維數組就是矩陣。在矩陣操作中,有一項叫轉置,是將矩陣元素位置的行列互換,比如原來在(1,2)這個位置的元素,會和(2,1)這個位置的元素進行互換。在Numpy中我們有兩種方式來實現數組的翻轉:
- transpose函數,將被翻轉目標A放到函數中,像這樣np.transpose(A)就可以了。
- .T,第二種辦法更加簡便,就行了直接在目標數組A後面加個.T。
代碼:
A = np.arange(0,8).reshape(4,2) B = np.transpose(A) C = A.T print (A, 'n', B, 'n', C)
講解:
A是一個4*2的數組,B和C分別通過兩種方式翻轉A,雖然函數不同,但是結果卻是一樣的。
運行結果:
[[0 1]
[2 3]
[4 5]
[6 7]]
[[0 2 4 6]
[1 3 5 7]]
[[0 2 4 6]
[1 3 5 7]]
數組連接
數組連接顧名思義是將兩個或多個數組按照一定的方式連接起來,常用的數組連接有以下幾種函數:
- concatenate函數,使用方式是把被連接的數組依次放進去,用逗號隔開,再用括號括起來;還有一個參數axis來指定按照哪一個軸連接。axis默認值是0,意思是沿着第一個軸連接,如果你設置成1,那麼就是沿着第二個軸連接。
- stack函數,它和concatenate函數有一點不同。stack函數更多是一種堆疊,會在原來的維度上增加一個維度;而concatenate不會增加維度。
- hstack函數,它是stack函數的變種,其中h的意思是horizontal,水平的。顧名思義,它會將數組按水平的方式連接。關鍵是hstack不像stack一樣增加維度,這一點是很好的。
- vstack函數,也是stack函數的變種,其中v的意思是vertical,垂直的。顧名思義,它會將數組按豎直的方式連接。
代碼:
A = np.array([[1,2],[3,4]]) B = np.array([[5,6],[7,8]]) print (np.concatenate((A,B),axis = 1)) print (np.stack((A,B),1)) print (np.hstack((A,B))) print (np.vstack((A,B)))
講解:
A和B都是2*2的數組,我們分別用四個函數去連接它們。第一個是concatenate函數,axis=1表示沿着第二個軸,也就是水平連接;第二個是stack函數,同樣是沿着第二個軸,在這裡我們省略了axis參數;第三個是hstack,豎直方向連接;第四個是vstack,水平方向連接。
運行結果:
[[1 2 5 6]
[3 4 7 8]]
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
[[1 2 5 6]
[3 4 7 8]]
[[1 2]
[3 4]
[5 6]
[7 8]]
數組分割
數組分割相當於數組連接的逆向操作,將一個大數組分割成好幾個數組。常用的函數有三個:
- split函數,這個函數有三個參數。第一個參數ary就是被分割的數組,第二參數叫indices_or_sections:果是一個整數,就用該數平均切分,如果是一個數組,為沿軸切分的位置(左開右閉),第三個參數axis是按照哪個軸切分。
- hsplit函數,水平方向上切分。
- vsplit函數,豎直方向上切分。
代碼:
A = np.arange(0,16).reshape(4,4) print (np.split(A,2)) print (np.hsplit(A,2)) print (np.vsplit(A,2))
講解:
A是一個4*4的二維數組,我們用了三種方式去分割。
運行結果:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]), array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
NumPy字符串
一直以來,我們處理的都是由數字組成的NumPy數組,其實NumPy中字符串也十分重要,尤其是在涉及到文件處理的時候,因為很多文件比如txt文檔只支持字符串(string)格式的讀寫。因此學會常用NumPy字符串函數是很有必要的。
字符串連接
負責字符串連接的有兩個函數,
- 第一個是加法add函數,字符串加法其實就是連接,將兩個字符串數組中的字符串連接在一起。
- 第二個是乘法multiply函數。字符串乘法可以看成加法的延展,將字符串複製好幾倍然後拼接在一起。
代碼:
import numpy as np print(np.char.add(['hello'],[' world'])) print(np.char.add(['hello','hi'],[' world',' universe'])) print(np.char.multiply('Love you ',3))
講解:
我們發現當加法函數中的數組裏面字符串元素不止一個的時候,連接會按照一一對應的方式配對連接。
運行結果:
['hello world']
['hello world' 'hi universe']
Love you Love you Love you
大小寫
表格中關於大小寫的函數有四個,我們分別來看看它們都是什麼功能。
- 第一個函數capitalize將首字母轉換成大寫,目的是針對寫文章的情景,需要把句子中第一個單詞的首字母大寫,比較實用。
- 第二個函數title是讓字符串的每個單詞的第一個字母變成大寫,和函數名呼應,這個函數的功能是針對文章標題用的,可以把字符串方便轉換成文章的標題。
- 第三個函數lower是將數組中每個元素轉換成小寫。
- 第四個函數upper是將數組中每個元素轉換成大寫。
代碼:
print (np.char.capitalize('love you')) print (np.char.title('i love you')) print (np.char.lower('LOVE YOU')) print (np.char.upper('love you'))
講解:
我們分別用例子嘗試了一下大小寫函數,還是非常容易的。
運行結果:
Love you
I Love You
love you
LOVE YOU
符號分割
分割操作在處理文件時候很重要,因為我們一般以一定格式,比如用逗號或者空格隔開數據而且每一行格式盡量一樣。我們介紹兩種分割函數,它們複製不同尺度:
- 第一個是split函數,通過指定分隔符對字符串進行分割,並返回數組。分隔符的默認值空格。
- 第二個是splitlines函數,從名字可以看出來分割行的,其根據換行符來分割字符串。
代碼:
print (np.char.split ('www.youtube.com', sep = '.')) print (np.char.splitlines('inlove you.'))
講解:
注意到調用行分割的時候,我們字符串中n是換行符,因此會在這個位置進行分割。
運行結果:
['www', 'youtube', 'com']
['i', 'love you.']
符號連接
既然有按照符號進行分割,其逆操作按符號進行連接。這個函數就是join.
代碼:
print (np.char.join([':','-'],['love','google']))
講解:
這裡有兩個連接符冒號和一橫,分別對應兩個字符串。
運行結果:
['l:o:v:e' 'g-o-o-g-l-e']
NumPy統計函數
最大,最小值
- amin函數用於計算數組中的最小值
- amax函數用於計算數組中的最大值
如果我們指定某個軸,那麼它們將會返回沿着軸的的最大或者最小的元素,即一個一維數組。當軸的參數是0的時候,會返回沿着縱軸最大或者最小元素;當軸的參數是1的時候,會返回沿着橫軸最大或者最小的元素。如果我們不設定軸的參數,那麼結果會返回這個數組的最大或者最小的元素。
代碼:
import numpy as np A = np.arange(12).reshape(3,4) print (np.amin(A,0)) print (np.amax(A,1)) print (np.amax(A))
講解:
我們建立了一個形狀為(3,4)的數組。第一個是求沿着縱軸每個列中最小的元素,因為數組有四列,因而會選出四個數字;第二個是求沿着橫軸每個行中最大的元素,因為數組有三行,因而會選出三個數字。最後我們沒有設定軸,因為會返回A數組中最大的元素。
運行結果:
[0 1 2 3]
[ 3 7 11]
11
中位數,平均值,方差
- median函數負責計算數組的中位數,其關於軸參數的設置規則和上面的是一樣,如果設置成0或1就會沿着縱軸或者橫軸計算中位數,如果不設置參數的話,就是計算整個數組的中位數
- mean函數會計算數組的平均值,也分為沿着軸計算或者整個數組計算,規則同上面一樣。
- 標準差函數std,方差函數是var。其中標準差的平方是方差。我們用最簡單的一位數組做實驗:
代碼:
A = np.arange(9).reshape(3,3) print (np.median(A)) print (np.median(A,0)) print (np.median(A,1)) print (np.mean(A)) print (np.mean(A,0)) print (np.mean(A,1))
講解:
這次我們建立了一個形狀為(3,3)的數組,把三種關於軸參數的情況都試了一次,大家對照規則自己想一下答案,再和打印結果對照一下。按照慣例,mean函數的三種用法都嘗試一遍。注意到,結果會同中位數結果一樣,因為A數組行或列的均值也是中位數。
運行結果:
4.0
[3. 4. 5.]
[1. 4. 7.]
4.0
[3. 4. 5.]
[1. 4. 7.]