Python進階之NumPy快速入門(三)

  • 2019 年 10 月 11 日
  • 筆記

引言

NumPy是Python的一個擴展庫,負責數組和矩陣運行。相較於傳統Python,NumPy運行效率高,速度快,是利用Python處理數據必不可少的工具

這個NumPy快速入門系列分為四篇,包含了NumPy大部分基礎知識,每篇閱讀時間不長,但內容含量高。大家最好親自碼一遍代碼,這樣可以更有收穫。

前面課程:

NumPy快速入門(一)

NumPy快速入門(二)

概要

1、掌握NumPy中的數組操作,輕鬆改變數組形狀;

2、掌握NumPy中的字符串,輕鬆應對文件處理;

3、掌握Python中的統計函數,輕鬆進行統計分析。

數組操作

我們將數組操作分成以下幾種類型,然後分別介紹

  • 數組變形
  • 數組翻轉
  • 數組連接
  • 數組分割

數組變形

可以實現數組變形的函數有好幾個:

  1. reshape,最常見的也是最主要的數組變形函數。可以將數組從一個形狀轉變成另外一個不同的形狀。
  2. flatten,可以將高維數組展開成一維。先建好一個數組A,然後輸出A.flatten()就可以完成降維。當然,我們可以選擇展開式的秩序order。如果order='F',就是按列展開;如果order='C',就是按行展開。
  3. 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中我們有兩種方式來實現數組的翻轉:

  1. transpose函數,將被翻轉目標A放到函數中,像這樣np.transpose(A)就可以了。
  2. .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]]

數組連接

數組連接顧名思義是將兩個或多個數組按照一定的方式連接起來,常用的數組連接有以下幾種函數:

  1. concatenate函數,使用方式是把被連接的數組依次放進去,用逗號隔開,再用括號括起來;還有一個參數axis來指定按照哪一個軸連接。axis默認值是0,意思是沿着第一個軸連接,如果你設置成1,那麼就是沿着第二個軸連接。
  2. stack函數,它和concatenate函數有一點不同。stack函數更多是一種堆疊,會在原來的維度上增加一個維度;而concatenate不會增加維度。
  3. hstack函數,它是stack函數的變種,其中h的意思是horizontal,水平的。顧名思義,它會將數組按水平的方式連接。關鍵是hstack不像stack一樣增加維度,這一點是很好的。
  4. 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]]

數組分割

數組分割相當於數組連接的逆向操作,將一個大數組分割成好幾個數組。常用的函數有三個:

  1. split函數,這個函數有三個參數。第一個參數ary就是被分割的數組,第二參數叫indices_or_sections:果是一個整數,就用該數平均切分,如果是一個數組,為沿軸切分的位置(左開右閉),第三個參數axis是按照哪個軸切分。
  2. hsplit函數,水平方向上切分。
  3. 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字符串函數是很有必要的。

字符串連接

負責字符串連接的有兩個函數,

  1. 第一個是加法add函數,字符串加法其實就是連接,將兩個字符串數組中的字符串連接在一起。
  2. 第二個是乘法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

大小寫

表格中關於大小寫的函數有四個,我們分別來看看它們都是什麼功能。

  1. 第一個函數capitalize將首字母轉換成大寫,目的是針對寫文章的情景,需要把句子中第一個單詞的首字母大寫,比較實用。
  2. 第二個函數title是讓字符串的每個單詞的第一個字母變成大寫,和函數名呼應,這個函數的功能是針對文章標題用的,可以把字符串方便轉換成文章的標題。
  3. 第三個函數lower是將數組中每個元素轉換成小寫。
  4. 第四個函數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

符號分割

分割操作在處理文件時候很重要,因為我們一般以一定格式,比如用逗號或者空格隔開數據而且每一行格式盡量一樣。我們介紹兩種分割函數,它們複製不同尺度:

  1. 第一個是split函數,通過指定分隔符對字符串進行分割,並返回數組。分隔符的默認值空格。
  2. 第二個是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.]