1. 程式人生 > 程式設計 >Python之Numpy的超實用基礎詳細教程

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 如果陣列包含欄位,則是要排序的欄位

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。