1. 程式人生 > >Python3基本工具包:Numpy

Python3基本工具包:Numpy

Numpy

NumPy是Python科學計算的基礎包。它提供了多維陣列物件、基於陣列的各種派生物件(例如,masked Array, 矩陣)。除此之外,還提供了各種各樣的加快陣列操作的例程,包括數學基本計算、邏輯、圖形操作、排序、選擇、輸入輸出,離散傅立葉變換、基礎線性代數、基礎統計操作、隨機模擬等等。

1 使用Numpy構建矩陣

陣列的建立可以使用numpy模組中的array()函式實現,一維陣列只需要給array()函式傳入一個列表或元組,二維陣列則是傳入巢狀的列表或元組。

# 輸入:
import numpy as np
a = np.array([1,2,3,4
,5]) print(a) b = np.array((1,2,3,4,5)) print(b) c = np.array([[1,4,7],[2,5,8],[3,6,9]]) print(c) print(a.shape) print(b.shape) print(c.shape) # 輸出: [1 2 3 4 5] [1 2 3 4 5] [[1 4 7] [2 5 8] [3 6 9]] (5,) (5,) (3, 3)

上面a和b為一維陣列,c為二維陣列,返回一個數組的行數和列數可使用shape方法。

2 元素的獲取

使用索引的方式,查詢一維陣列和二維陣列的元素。一維陣列的索引與列表、元組的索引完全一致,這裡就不在贅述;二維陣列的索引就稍微有點複雜。

# 輸入:
import numpy as np
a = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(a[:,2],'\n') # 獲取二維陣列的第三列
print(a[1,:],'\n') # 獲取二維陣列的第二行
print(a[1,1],'\n') # 獲取二維陣列第二行第二列的元素
print(a[[0,2],:],'\n') # 獲取二維陣列第一、第三行  
print(a[:,[1,2]],'\n') # 獲取二維陣列第二、第三列
print(a[[1,2],[0,1]],'\n') # 獲取二維陣列第二行第一列的交叉元素和第三行第二列的交叉元素
# 輸出:
[7
8 9] [2 5 8] 5 [[1 4 7] [3 6 9]] [[4 7] [5 8] [6 9]] [2 6]

注意:
1. print()函式中的’\n’,目的用來換行。
2. 最後一個返回的結果不是一個矩陣,而是相當於座標為[1,0]和[2,1]對應的兩個值。下面的例子才是返回一個矩陣。

# 輸入:
import numpy as np
a = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(a[[0,1],:][:,[1,2]],'\n') # 返回第一第二行和第二第三列的交叉元素矩陣。
# 輸出:
[[4 7]
 [5 8]] 

3 數學函式

np.abs # 取絕對值
np.fabs # 取絕對值
np.sqrt # 算術平方根
np.square # 平方
np.exp # 指數
np.log2 # 對數
np.log10 # 對數
np.log(x,base) # 對數
np.sign # 符號函式(大於0的數返回1、小於0的數返回-1、0返回0值)
np.cell # 向上取整
np.floor # 向下取整
np.rint  # 返回最近的整數
np.isnan # 判斷是否缺失
np.isfinite # 判斷是否有限
np.isinf # 判斷是否無限
np.power # 冪運算
np.mod # 餘數

4 統計函式

np.max # 最大值
np.fmax # 浮點型的最大值
np.mim # 最小值
np.fmin # 浮點型的最小值
np.sum # 求和
np.mean # 均值
np.std # 標準差
np.var # 方差
np.median # 中位數

5 對映函式

apply_along_axis()函式與R語言中的apply函式用法一致,可以針對某個軸的方向進行函式操作,同樣,在pandas模組的DataFrmae物件中,可以使用apply函式達到相同的效果。
語法:

numpy.apply_along_axis(func, axis, arr, *args, **kwargs)

必選引數:func, axis, arr。其中func是我們自定義的一個函式;axis表示函式func對陣列arr作用的軸,axis=1表示操作行,axis=0表示操作列;arr是一個數組,即函式計算的物件。
可選引數:*args, **kwargs。都是func()函式額外的引數。
返回值:numpy.apply_along_axis()函式返回的是一個根據func()函式以及維度axis運算後得到的的陣列。

# 輸入:
import numpy as np
a = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(a)
print(np.apply_along_axis(np.mean,1,a)) # 計算矩陣每行的均值
print(np.apply_along_axis(np.sum,0,a)) # 計算矩陣每列的和
# 輸出:
[[1 4 7]
 [2 5 8]
 [3 6 9]]
[ 4.  5.  6.]
[ 6 15 24]

6 隨機數生成

numpy模組中的子模組random提供了很多產生隨機數的方法,幫我們產生偽資料帶來了極大的方便。有時候為了使每次產生的隨機數都相同,就需要設定固定的隨機種子(比如1),設定隨機種子可以呼叫seed函式實現。

# 輸入:
import numpy as np
np.random.seed(1)
a = np.random.random()
print(a)
np.random.seed(1)
a = np.random.random()
print(a)
np.random.seed()
a = np.random.random()
print(a)
np.random.seed()
a = np.random.random()
print(a)
# 輸出:
0.417022004702574
0.417022004702574
0.10266849881339712
0.7271798615004479

7 離散分佈

7.1 二項分佈

二項分佈在概率論和統計學中,二項分佈是n個獨立的是/非試驗中成功的次數的離散概率分佈,其中每次試驗的成功概率為p。所以n次中有k次成功的概率可以表示為:

f(k;n,p)=Cnkpk(1p)nk

np.random.binomial(n,p,size=x)函式返回的是x個符合二項分佈的隨機數,另外size引數可以用來控制生成的隨機數的形狀,如size = 10表示一個10個長度的一維陣列;size = (3,5)表示一個3×5的矩陣。

輸入:
import numpy as np
np.random.seed(1)
n, p = 2, .5
a = np.random.binomial(n, p, size=10)
print(a)
b = np.random.binomial(n, p, size=(3,5))
print(b)
輸出:
[1 1 0 1 0 0 0 1 1 1]
[[1 1 0 2 0]
 [1 1 1 0 0]
 [2 2 1 1 2]]

7.2 泊松分佈

大量事件是有固定頻率的,比如某路口平均每天發生事故次數2次,那麼想知道在此處一天內發生4次事故的概率是多少就需要用到泊松分佈:描述某段時間內,事件具體的發生概率。公式如下:

P(N(t)=n)=(λt)neλtn!

P 表示概率,N表示某種函式關係,t 表示時間,n 表示數量,一天內發生2次事故的概率,就表示為 P(N(1) = 2) ,λ 表示事件的頻率。
故在此處一天內發生4次事故的概率為:

P(N(1)=4)=(21)4e214!0.09

np.random.poisson(lam, size=x)返回的是x個符合泊松分佈的隨機數,lam相當於λ,也即是事件的頻率。

# 輸入:
import numpy as np
np.random.seed(1) #設定隨機種子,保證每次執行都會出現相同的隨機數
r3 = np.random.poisson(lam=6,size=10)
print(r3,'\n')
r4 = np.random.poisson(lam=(10,50,20),size=(5,3))
print(r4,'\n')
# 輸出:
[2 3 7 7 4 6 5 6 2 4] 

[[11 52 13]
 [12 34 22]
 [17 61 19]
 [16 55 26]
 [12 45 22]]

上面例子生成3列泊松分佈的資料,lamda引數分別取10,50,20,表示單位時間內某件事發生的頻次。

8 連續分佈

8.1 正態分佈

該分佈也成高斯分佈,呈現兩頭低,中間高,左右對稱的倒鐘形狀,是連續分佈中使用最頻繁的一種分佈。正態分佈由兩個引數描述:分佈的期望值μ和方差σ^2 ,當μ=0、σ^2 =1時,稱為標準正態分佈。其公式如下:

f(x;μ,σ)=1σ2πe(xμ)22σ2

np.random.normal(loc,scale,size=x)返回的是x個符合正態分佈的隨機數,loc為均值,scale為標準差。

# 輸入:
import numpy as np
np.random.seed(1) #設定隨機種子,保證每次執行都會出現相同的隨機數
# 均值為2,標準差為3的正態分佈
r5 = np.random.normal(loc = 2, scale = 3, size = 10)
print(r5,'\n')
r6 = np.random.normal(loc = 2, scale = 3, size = (3,5))
print(r6)
# 輸出:
[ 6.87303609  0.16473076  0.41548474 -1.21890587  4.59622289 -4.90461609
  7.23443529 -0.2836207   2.95711729  1.25188887] 

[[ 6.38632381 -4.18042213  1.03274839  0.84783694  5.40130833]
 [-1.2996738   1.48271538 -0.63357525  2.12664124  3.74844564]
 [-1.30185753  5.43417113  4.70477216  3.50748302  4.70256785]]

8.2 其他常用分佈

# 輸入:
import numpy as np
np.random.seed(1) #設定隨機種子,保證每次執行都會出現相同的隨機數
r7 = np.random.standard_t(df = 3, size = (2,3)) # 自由度為3的t分佈
print(r7,'\n')
r8 = np.random.f(dfnum = 2, dfden = 5, size = (3,5)) # 自由度為25的f分佈
print(r8,'\n')
r9 = np.round(np.random.uniform(size = (3,4), low = 1, high = 10),0) # 110之間的均勻分佈,並四捨五入取整
print(r9,'\n')
# 輸出:
[[ 2.52088116 -1.13756823 -1.09478858]
 [-1.70781334  0.40792799 -0.50672438]] 

[[ 0.12167855  0.65503307  1.71293129  1.44691121  2.54191617]
 [ 0.06964423  6.16774986  0.04916023  0.28635355  4.41972259]
 [ 1.60388551  1.11849708  0.01890469  2.49884978  3.6290282 ]] 

[[  9.   4.   8.   8.]
 [  9.   7.   8.   4.]
 [  3.   9.   5.  10.]]

9 資料載入

numpy模組還提供了讀取資料與寫資料的函式,方便我們將外部資料檔案讀入到Python的工作環境中。這裡推薦兩個讀資料的函式:np.loadtxt()和np.genfromtxt()

# 輸入:
data1 = np.loadtxt(fname = 'loadtxt.txt', delimiter = ',', skiprows = 1)
date2 = np.genfromtxt(fname = 'loadtxt.txt', delimiter = ',', skip_header = 1, usecols = [0,2])
print(data1,'\n')
print(date2)
# 輸出:
[] 

[]

注意:
- fname:指定外部檔案的路徑
- delimiter:指定檔案中資料列的分隔符
- skiprows:指定讀數時跳過的行數
- skip_header:指定跳過首行
- usecols:指定讀取的資料列
- loadtxt函式和genfromtxt函式讀入資料形成陣列,故必須要求讀進來的資料一定是數值型資料,否則會報錯。

10 資料寫出

通過使用numpy模組中的savetxt函式實現python資料的寫出,函式語法如下:

np.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ')

其中:

  • fname:指定資料寫出的路徑
  • X:指定需要寫出的資料
  • fmt:指定輸出資料的格式,預設科學計演算法
  • delimiter:指定資料列之間的分隔符,預設空格符
  • newline:指定新行的識別符號,預設換行
  • header:指定輸出資料首行值
  • footer:指定輸出資料的末行值
  • comments:指定註釋符,預設“#”