Python之Numpy的超實用基礎詳細教程
Numpy在python中屬於非常常用的包,無論是機器學習搭配pandas,還是資料視覺化搭配pylab都是很正常的搭配。
Numpy
numpy的官方中文文件:NumPy 中文
NumPy是使用Python進行科學計算的基礎軟體包。除其他外,它包括:
- 功能強大的N維陣列物件;
- 精密廣播功能函式;
- 整合C/C+和Fortran程式碼的工具;
- 強大的線性代數、傅立葉變換和隨機數功能。
更簡單的說,Numpy是Python的Matlab數學計算包。使用它,python可以更簡單便捷地對矩陣向量進行計算。
一般來說,我們引用該包並將其簡稱為np:
import numpy as np
Numpy的ndarry物件
ndarray的建立
Numpy中最重要的資料型別就是:N維陣列物件ndarray。它是一系列同類型資料的集合,以0下標為開始進行集合中元素的索引。
它具有以下兩個特點:
- ndarray物件是用於存放同類型元素的多維陣列;
- ndarray中的每個元素在記憶體中都有相同儲存大小的區域。
建立一個ndarray物件:
np.array(object,dtype = None,copy = True,order = None,subok = False,ndmin = 0)
引數說明:
名稱 | 描述 |
---|---|
object | 陣列或巢狀的數列 |
dtype | 陣列元素的資料型別,可選 |
copy | 物件是否需要複製,可選 |
order | 建立陣列的樣式,C為行方向,F為列方向,A為任意方向(預設) |
subok | 預設返回一個與基類型別一致的陣列 |
ndmin | 指定生成陣列的最小維度 |
一般而言,並不需要記住這麼多可選引數:
import numpy as np if __name__ == "__main__": x = np.array([1,2,3]) print(x)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[1 2 3]
當然,除了之前的array方法建立ndarray物件之外,還提供了另外的幾種建立方式:
np.empty(shape,dtype = float,order = 'C') # 指定形狀的未初始化陣列 np.zeros(shape,order = 'C') # 指定形狀的全0陣列 np.ones(shape,order = 'C') # 指定形狀的全1陣列 np.arange(start = 0,stop,step = 1,dtype) # 從起始值到終止值(不包含)時,按步長從範圍內建立陣列 np.linspace(start,num = 50,endpoint = True,retstep = False,dtype = None) # 從起始值到終止值(預設包含)建立一個等差陣列的一維陣列 np.logspace(start,base = 10.0,dtype = None) # 從起始值到終止值(預設包含)建立一個等比陣列的一維陣列
Numpy也提供了從python其他型別直接轉換成ndarray的方式:
np.asarray(a,order = None) # 列表形式 np.frombuffer(buffer,count = -1,offset = 0) # 以流的形式讀入 np.fromiter(iterable,dtype,count=-1) # 從可迭代物件中,以迭代器的形式讀入
例如:
import numpy as np if __name__ == "__main__": a = [[1,3],[4,5]] b = 'Hello World' c = iter(range(5)) x = np.asarray(a) y = np.frombuffer(b,dtype = 'S1') z = np.fromiter(c,dtype = float) print(x) print(y) print(z)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[list([1,3]) list([4,5])]
['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']
[0. 1. 2. 3. 4.]
ndarray的資料結構
Numpy支援很多的資料型別,下面就簡單地列舉一下:
名稱 | 描述 |
---|---|
bool_ | 布林型資料型別(True或者False) |
int_/int8/int16/int32/int64 | 有符號整數 |
uint8/uint16/uint32/uint64 | 無符號整數 |
float_/float16/float32/float64 | 浮點數 |
complex_/complex64/complex128 | 複數 |
但如果是自定義的資料型別,就需要通過dtype來確定了:
numpy.dtype(object,align,copy)
引數說明:
名稱 | 描述 |
---|---|
object | 要轉換為的資料型別物件 |
align | 如果為true,填充欄位使其類似C的結構體 |
copy | 複製dtype物件 ,如果為false,則是對內建資料型別物件的引用 |
例如,可以建立一個student的物件:
import numpy as np if __name__ == "__main__": student = np.dtype([('name','S20'),('age','i8'),('score','f4')]) a = np.array([('zhangsan',18,80),('lisi',19,85)],dtype=student) print(a)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[('zhangsan',80.) ('lisi',85.)]
ndarray的屬性
ndarray有兩個非常常用的屬性,shape和size。shape表示陣列的維度,對於二維陣列而言,就是其行數和列數;size表示陣列元素的總個數,對於二維陣列而言,就是行數與列數的相乘。
例如:
import numpy as np if __name__ == "__main__": a = np.array([[1,5,6]]) print(a.shape) print(a.size)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
(2,3)
6
當然,ndarray物件提供了兩種方式在不改變資料內容的情況下,改變一個數組的格式。但兩種方式有所區別:
import numpy as np if __name__ == "__main__": a = np.array([[1,6]]) a.shape = (3,2) # 直接改變本體 print(a) b = a.reshape(2,3) # 本體不改變,將改變後的物件返回 print(b)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[1 2]
[3 4]
[5 6]]
[[1 2 3]
[4 5 6]]
ndarray的內容訪問
ndarray物件的內容可以通過索引或切片來訪問和修改,與python中list的切片操作一樣。
ndarray既可以基於下標進行切片,也可以通過內建的slice函式,並設定start,stop及step引數進行,從原陣列中切割出一個新陣列。
例如:
import numpy as np if __name__ == "__main__": a = np.arange(10) b = a[1:7:1] s = slice(1,7,1) c = a[s] print(a) print(b) print(c)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[0 1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6]
[1 2 3 4 5 6]
對於冒號:的解釋:
- 如果是一維陣列,如果只放置一個引數,如[2],將返回與該索引相對應的單個元素。如果為[2:],表示從該索引開始以後的所有項都將被提取。如果使用了兩個引數,如[2:7],那麼則提取兩個索引(不包括停止索引)之間的項;
- 如果是多維陣列,使用,區分維數。
例如:
import numpy as np if __name__ == "__main__": a = np.arange(25) a.shape = (5,5) b = a[1:4,2:4] print(a) print(b)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
[[ 7 8]
[12 13]
[17 18]]
ndarray除了基於下標進行切片,還有一些高階索引方式,比如布林索引、花式索引。
例如:
import numpy as np if __name__ == "__main__": a = np.arange(25) a.shape = (5,5) b = a[a > 6] c = a[[3,4]] print(a) print(b) print(c)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
[ 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
[[15 16 17 18 19]
[10 11 12 13 14]
[20 21 22 23 24]]
其他
判斷元素物件是都為NaN:
np.isnan(...)
Numpy的廣播
如果兩個ndarray:a和b形狀相同,即滿足a.shape==b.shape,那麼a與b的算數結果就是a與b陣列對應位做算術運算。這要求維數相同,且各維度的長度相同。
例如:
import numpy as np if __name__ == "__main__": a = np.array([1,3]) b = np.array([1,3]) c = a + b d = a * b print(c) print(d)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[2 4 6]
[1 4 9]
而,廣播是Numpy對不同形狀(shape)的ndarray進行數值計算的方式,對ndarray的算術運算通常在相應的元素上進行
。
怎麼才算是相應的元素呢?
雖然,廣播是對不同形狀(shape)而言,但其實還是要滿足兩個條件:列數相同,有一個行數為1。在這個前提下,每行的相同列的元素就是相對應的元素。
直接看文字可能還是有點不太能理解,可以看一下例子:
import numpy as np if __name__ == "__main__": a = np.array([[1,6],[7,8,9]]) b = np.array([1,3]) c = a + b d = a * b print(c) print(d)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]]
[[ 1 4 9]
[ 4 10 18]
[ 7 16 27]]
所謂廣播就是:當列數相同的時候,行數為1的ndarray會進行擴行的操作,增加的行數內容與原行的內容相同。
擴行的實現可以通過tile函式實現:
np.tile(obj,(行,列)) # 在行上和列上分別重複一定的次數
所以,上文的廣播也可以通過下面的方式來代替:
import numpy as np if __name__ == "__main__": a = np.array([[1,3]) bb = np.tile(b,(3,1)) c = a + bb d = a * bb print(bb) print(c) print(d)
執行該指令碼:
yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[1 2 3]
[1 2 3]
[1 2 3]]
[[ 2 4 6]
[ 5 7 9]
[ 8 10 12]]
[[ 1 4 9]
[ 4 10 18]
[ 7 16 27]]
ndarray的函式
ndarray提供了很多的數學函式、算術函式、排序函式,以便進行運算。
ndarray的數學函式,例如:
np.pi # 圓周率 np.sin(obj) # 三角運算 np.cos(obj) np.tan(obj) np.arcsin(obj) # 反三角運算 np.arccos(obj) np.arctan(obj) np.degrees(obj) # 將弧度值轉換為角度值 np.around(obj,decimals) # 返回ndarray每個元素的四捨五入值,decimals為舍入的小數位數,預設為0 np.floor(obj) # 向下取整 np.ceil(obj) # 向上取整
ndarray的算術函式,例如:
np.add(obj1,obj2) # 加減乘除運算,與+-*/效果一致,需要符合廣播原則 np.subtract(obj1,obj2) np.multiply(obj1,obj2) np.divide(obj1,obj2) np.mod(obj1,obj2) # 求餘數運算 np.reciprocal(obj) # 元素取倒數 np.power(obj1,obj2) # 計算前引數為底,後引數為冪的值
ndarray的排序函式,例如:
np.sort(obj,axis=1,kind='quicksort',order)
引數說明:
名稱 | 描述 |
---|---|
obj | 陣列或巢狀的數列 |
axis | axis=0按列排序,axis=1按行排序 |
kind | ‘quicksort'、‘mergesort'、‘heapsort' |
order | 如果陣列包含欄位,則是要排序的欄位 |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。