Python——Bumpy基礎知識(一)
一、Numpy的引入
1、標準的Python 中用列表(list)儲存一組值,可以當作陣列使用。但由於列表的元素可以是任何物件,因此列表中儲存的是物件的指標。對於數值運算來說,這種結構顯然比較浪費記憶體和CPU 計算 2、雖然Python 提供了array 模組,它和列表不同,能直接儲存數值,但是由於它不支援多維陣列,也沒有各種運算函式,因此也不適合做數值運算。 NumPy 的誕生彌補了這些不足。 NumPy 提供了兩種基本的物件:ndarray(n-dimensional array object)和ufunc(universal function object)。 ndarray(下文統一稱之為陣列)是儲存單一資料型別的多維陣列,而ufunc 則是能夠對陣列進行處理的函式。二、Numpy簡介
Numpy 是一個專門用於矩陣化運算、科學計算的開源Python庫,Numpy將Python相當於變成一種免費的更強大的Matlab系統
優勢:
1、強大的 ndarray 多維陣列結構
2、成熟的函式庫
3、用於整合C/C++和Fortran程式碼的工具包
4、實用的線性代數、傅立葉變換和隨機數模組
5、Numpy 和稀疏矩陣運算包scipy 配合使用非常方便
三、語法簡介
首先,函式庫的匯入
1 import numpy as np 2 #生成簡單的一維矩陣 3 a=np.array([1,2,3,4]) 4 #生成簡單的二維矩陣 5 c=np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10]])6 #獲取型別 7 print(type(a)) 8 #陣列的大小可以通過其屬性獲得 9 print (a.shape,b.shape) 10 #列印陣列 11 print (c) 12 #可以通過修改陣列的shape屬性,在爆出陣列元素個數不變的情況下,改變陣列每個軸的長度 13 c.shape=4,3 14 ##注意,並不是對陣列進行轉置,而是隻改變每個軸的大小 15 print(c) 16 #當某個軸的元素為-1時,將根據陣列元素的閣主自動計算此軸的長度 17 c.shape=2,-1 18 print(c) 19 #使用reshape方法可以建立一個改變了尺寸的新陣列,原陣列保持不變20 d=a.reshape((2,2)) 21 print(d) 22 print(a) 23 d=c.reshape((3,3))#不能講一個12個元素的陣列分成3*3,會報錯 24 print(c) 25 #陣列a和d實際上時共享資料儲存記憶體區域,修改其一另一個也會改變
輸出
<class 'numpy.ndarray'>#列印型別
#shape (4,) (3, 4)
#列印陣列
[[ 1 2 3 4] [ 4 5 6 7] [ 7 8 9 10]]
#修改軸長 [[ 1 2 3] [ 4 4 5] [ 6 7 7] [ 8 9 10]]
#修改軸長,其一引數為-1 [[ 1 2 3 4 4 5] [ 6 7 7 8 9 10]]
#reshape [[1 2] [3 4]] [1 2 3 4]
#錯誤 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-13-430fc5495966> in <module>() 21 print(d) 22 print(a) ---> 23 d=c.reshape((3,3)) 24 print(c) ValueError: cannot reshape array of size 12 into shape (3,3)
上面的例子都是先建立一個Python序列,然後通過array函式將其轉換為陣列,這樣做顯然效率不高。因此NumPy提供了很多專門用來建立陣列的函式。
初始化陣列:
1 import numpy as np 2 a=np.arange(0,1,0.1) 3 print("a=",a) 4 b=np.linspace(0,1,10) 5 print("b=",b) 6 c=np.linspace(0,1,10,endpoint=False) 7 print("c=",c) 8 d=np.logspace(0,2,20) 9 print("d=",d) 10 e=np.empty((2,3),np.int) 11 print("e=",e) 12 f=np.zeros(4,np.float) 13 print("f=",f)
執行結果:
a= [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9] b= [0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556 0.66666667 0.77777778 0.88888889 1. ] c= [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9] d= [ 1. 1.27427499 1.62377674 2.06913808 2.6366509 3.35981829 4.2813324 5.45559478 6.95192796 8.8586679 11.28837892 14.38449888 18.32980711 23.35721469 29.76351442 37.92690191 48.32930239 61.58482111 78.47599704 100. ] e= [[ 0 0 1863334416] [ 588 0 -2147483648]] f= [0. 0. 0. 0.]
arange函式類似於python的range函式,通過指定開始值、終值和步長來建立一維陣列,注意陣列不包括終值。
linspace函式通過指定開始值、終值和元素個數來建立一維陣列,可以通過endpoint關鍵字指定是否包括終值,預設設定是包括終值:
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
Endpoint 如果是真,則一定包括stop,如果為False,一定不會有stop
#numpy.logspace(start, stop, num, endpoint=true, base=10, dtype)
#資料頭一定是base^start,若endpoint=True,資料尾為base^end,其餘資料為base^(start,end)
logspace函式和linspace類似,不過它建立等比數列,下面的例子產生1(10^0)到100(10^2)、有20個元素的等比數列。
1 >>> a = np.arange(10) 2 >>> a[5] # 用整數作為下標可以獲取陣列中的某個元素 3 5 4 >>> a[3:5] # 用範圍作為下標獲取陣列的一個切片,包括a[3]不包括a[5] 5 array([3, 4]) 6 >>> a[:5] # 省略開始下標,表示從a[0]開始 7 array([0, 1, 2, 3, 4]) 8 >>> a[:-1] # 下標可以使用負數,表示從陣列後往前數 9 array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 10 >>> a[2:4] = 100,101 # 下標還可以用來修改元素的值 11 >>> a 12 array([ 0, 1, 100, 101, 4, 5, 6, 7, 8, 9]) 13 14 >>> a[1:-1:2] # 範圍中的第三個引數表示步長,2表示隔一個元素取一個元素 15 array([ 1, 101, 5, 7]) 16 >>> a[::-1] # 省略範圍的開始下標和結束下標,步長為-1,整個陣列頭尾顛倒 17 array([ 9, 8, 7, 6, 5, 4, 101, 100, 1, 0]) 18 >>> a[5:1:-2] # 步長為負數時,開始下標必須大於結束下標 19 array([ 5, 101]) 20 21 >>> b = a[3:7] # 通過下標範圍產生一個新的陣列b,b和a共享同一塊資料空間 22 >>> b 23 array([101, 4, 5, 6]) 24 >>> b[2] = -10 # 將b的第2個元素修改為-10 25 >>> b 26 array([101, 4, -10, 6]) 27 >>> a # a的第5個元素也被修改為10 28 array([ 0, 1, 100, 101, 4, -10, 6, 7, 8, 9])
除了使用下標範圍存取元素之外,NumPy還提供了兩種存取元素的高階方法。
1、使用整數序列
當使用整數序列對陣列元素進行存取時,將使用整數序列中的每個元素作為下標,整數序列可以是列表或者陣列。使用整數序列作為下標獲得的陣列不和原始陣列共享資料空間。
1 >>> x = np.arange(10,1,-1) 2 >>> x 3 array([10, 9, 8, 7, 6, 5, 4, 3, 2]) 4 >>> x[[3, 3, 1, 8]] # 獲取x中的下標為3, 3, 1, 8的4個元素,組成一個新的陣列 5 array([7, 7, 9, 2]) 6 >>> b = x[np.array([3,3,-3,8])] #下標可以是負數 7 >>> b[2] = 100 8 >>> b 9 array([7, 7, 100, 2]) 10 >>> x # 由於b和x不共享資料空間,因此x中的值並沒有改變 11 array([10, 9, 8, 7, 6, 5, 4, 3, 2]) 12 >>> x[[3,5,1]] = -1, -2, -3 # 整數序列下標也可以用來修改元素的值 13 >>> x 14 array([10, -3, 8, -1, 6, -2, 4, 3, 2])
注:”:”用以表示當前維度的所有子模組 ; “-1”用以表示當前維度所有子模組最後一個;”負號用以表示從後往前數的元素”
2、使用布林陣列
當使用布林陣列b作為下標存取陣列x中的元素時,將收集陣列x中所有在陣列b中對應下標為True的元素。
使用布林陣列作為下標獲得的陣列不和原始陣列共享資料空間,注意這種方式只對應於布林陣列,不能使用布林列表。
1 >>> x = np.arange(5,0,-1) 2 >>> x 3 array([5, 4, 3, 2, 1]) 4 5 >>> x=np.random.rand(10) 6 >>> x 7 array([ 0.5993579 , 0.68693925, 0.74380945, 0.40993085, 0.72345401, 0.64499497, 0.48715468, 0.80924589, 0.43362779, 0.06554248]) 8 >>> x>0.5 #對每個元素都比較 9 array([ True, True, True, False, True, True, False, True, False, False], dtype=bool) 10 >>> x[x>0.5] #將它當做索引傳回原陣列,只獲取那些>0.5的 11 array([ 0.5993579 , 0.68693925, 0.74380945, 0.72345401, 0.64499497, 0.80924589]) 12 >>> np.all(x<1) #測試x<1所返回的陣列(傳給all)中所有元素是否都等價True 13 >>> a=np.array([1,2,3]) 14 >>> b=np.array([3,2,1]) 15 >>> a>b #對應位置作比較 16 array([False, False, True], dtype=bool) 17 >>> a[a==b] #獲取一樣的 18 array([2]) 19 >>>(a==b).all() 20 >>>(a==b).any() 21 >>> np.any([1,2,3,4]) #如果傳入的陣列中有至少一個元素等價True都返回True 22 True