前言
NumPy 是 Python 的運算套件,提供陣列 (ndarray)、矩陣 (matrix)……等常用的數學工具,運算速度比 Python 內建的資料格式快很多。NumPy 已經將許多常用的運算寫成函式,如果能善用這些函式,可以大幅加快程式的運算速度。以下是一些我目前常用到的陣列相關函式整理,如果之後有用到新的函式會再新增內容。請注意,以下的程式碼都省略了 import numpy as np。
產生陣列
手動輸入
一維陣列語法
np.array([元素1, 元素2, 元素3, 元素4, 元素5], dtype = 格式)
二維陣列語法
np.array([(元素11, 元素12, 元素13, 元素14, 元素15), (元素21, 元素22, 元素23, 元素24, 元素25)], dtype = 格式)
數值格式可以是 整數 (int)、浮點數 (float)、複數 (complex),如果不指定的話系統會自動判斷。
範例:
in[1]: np.array([1, 2, 3, 4, 5])
out[1]: array([1, 2, 3, 4, 5])
in[2]: np.array([1, 2, 3, 4, 5], dtype = float)
out[2]: array([1., 2., 3., 4., 5.])
in[3]: np.array([1, 2, 3, 4, 5], dtype = complex)
out[3]: array([1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j])
in[4]: np.array([(1, 2, 3, 4, 5), (6, 7, 8, 9, 10)], dtype = int)
out[4]: array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
np.dtype
功能:取得資料格式
假設陣列A為 array([1, 2, 3, 4, 5]),如果想要知道資料的格式,可以使用
in[1]: A.dtype
out[1]: dtype('int64')
取得陣列長度或維度
假設陣列A為 array([1, 2, 3, 4, 5]),如果想要知道陣列A的長度,可以使用
in[1]: len(A)
out[1]: 5
假設陣列B為 array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10]]),維度為(2, 5),如果想要知道陣列B的維度,可以使用
in[2]: B.shape
out[2]: (2, 5)
如果使用以下的寫法,回傳的數值是列數。
in[3]: len(B)
out[3]: 2
如果使用以下的寫法,回傳的數值是第0列裡的元素數量。
in[4]: len(B[0])
out[4]: 5
np.zeros
功能:產生指定長度的一維陣列,每個元素皆為0。
語法
np.zeros(長度)
範例:
in[1]: np.zeros(10)
out[1]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.ones
功能:產生指定長度的一維陣列,每個元素皆為1。
語法
np.ones(長度)
範例:
in[1]: np.ones(10)
out[1]: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.arange
功能:產生一維陣列,第一個元素為起始值,下一個元素為這個元素加上間隔,不包含結束值。起始值預設為0,間隔預設為1。
語法:
np.arange(起始值, 結束值, 間隔)
範例:
in[1]: np.arange(10)
out[1]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
in[2]: np.arange(1, 10)
out[2]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])
in[3]: np.arange(1, 10, 2)
out[3]: array([1, 3, 5, 7, 9])
np.linspace
功能:產生一維陣列,第一個元素為起始值,最後一個元素為結束值,將兩者之間均勻分割為指定的數量-1。
語法:
np.linspace(起始值, 結束值, 數量)
範例:
in[1]: np.linspace(0, 1, 11)
out[1]: array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
操作陣列
取出元素值
陣列的的索引值 (index) 從0開始,假設陣列A為array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),取出索引值為3的元素,語法為
in[1]: A[3]
out[1]: 3
取出索引值為3到7的元素,語法為
in[2]: A[3:8]
out[2]: array([3, 4, 5, 6, 7])
取出索引值為0到倒數第3個元素,語法為
in[3]: A[:-2]
out[3]: array([0, 1, 2, 3, 4, 5, 6, 7])
取出最後1個元素,語法為
in[4]: A[-1]
out[4]: 9
反方向取出所有的元素,語法為
in[5]: A[::-1]
out[5]: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
四則運算
假設陣列A為 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),可以一次將所有的元素同時加、減、乘、除,語法為
in[1]: A + 1
out[1]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
in[2]: A - 1
out[2]: array([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8])
in[3]: A * 2
out[3]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
in[4]: A / 2
out[4]: array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])
假設陣列B為 array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),可以一次將兩個陣列中所有的元素同時加、減、乘、除,語法為
in[5]: A + B
out[5]: array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28])
in[6]: A - B
out[6]: array([-10, -10, -10, -10, -10, -10, -10, -10, -10, -10])
in[7]: A * B
out[7]: array([ 0, 11, 24, 39, 56, 75, 96, 119, 144, 171])
in[8]: A / B
out[8]: array([0. , 0.09090909, 0.16666667, 0.23076923, 0.28571429,
0.33333333, 0.375 , 0.41176471, 0.44444444, 0.47368421])
np.sum
功能:將陣列中所有元素的值相加。
語法:
np.sum(陣列名稱)
假設陣列A為 array([1, 2, 3, 4, 5]),則語法為
in[1]: np.sum(A)
out[1]: 15
np.min
功能:找出陣列中所有元素的最小值。
語法:
np.min(陣列名稱)
假設陣列A為 array([1, 2, 3, 4, 5]),則語法為
in[1]: np.min(A)
out[1]: 1
np.max
功能:找出陣列中所有元素的最大值。
語法:
np.max(陣列名稱)
假設陣列A為 array([1, 2, 3, 4, 5]),則語法為
in[1]: np.max(A)
out[1]: 5
np.diff
功能:將陣列下一個元素與這一個元素相減。
語法:
np.diff(陣列名稱)
假設陣列A為 array([1, 2, 4, 7, 11, 16]),則語法為
in[1]: np.diff(A)
out[1]: array([1, 2, 3, 4, 5])
如果想要用 Python 內建的串列 (list) 格式做到相同的效果,需要使用以下的寫法
B = [1, 2, 4, 7, 11, 16]
C = []
for i in range(len(B) - 1):
C.append(B[i+1] - B[i])
print(C)
np.clip
功能:將陣列中所有元素的值限制在指定的範圍內。
語法:
np.clip(最小值, 最大值)
假設陣列A為 array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),如果要將元素值限制在 0.3 和 0.8 之間,則語法為
in[1]: A.clip(0.3, 0.8)
out[1]: array([0.3, 0.3, 0.3, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.8, 0.8])
np.where
功能:回傳陣列當中符合條件的元素索引值。
語法:
np.where(陣列及條件)
假設陣列A為 array([ 0, 2, 4, 6, 8, 10]),如果要找所有大於5的元素索引值,則語法為
in[1]: np.where(A > 5)
out[1]: (array([3, 4, 5]),)
我們可以把回傳值傳給另一個陣列,假設陣列B為 array([10, 12, 14, 16, 18, 20]),如果想要取出符合 A > 5 對應的元素,則語法為
in[2]: B[np.where(A > 5)]
out[2]: array([16, 18, 20])
np.reshape
功能:將陣列改變成指定的維度,可以到3個以上的維度,但是這樣很難想像陣列的樣子,我通常只用到二維陣列。
語法:
np.reshape(維度1, 維度2)
假設陣列A為 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),如果要將陣列維度改為(2, 5),語法為
in[1]: A.reshap(2, 5)
out[1]: array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
也可以將產生陣列以及改變維度兩件事一起完成,語法為
in[2]: np.arange(10).reshape(2, 5)
out[2]: array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
np.T
功能:將陣列中的元素行、列對調,通常會接在陣列物件之後。
假設陣列A為 array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]),若要將陣列轉置,語法為:
in[1]: A.T
out[1]: array([[0, 5],
[1, 6],
[2, 7],
[3, 8],
[4, 9]])
np.vstack
功能:將陣列以垂直方向疊合。
假設陣列A為 array([0, 1, 2, 3, 4])、陣列B為 array([5, 6, 7, 8, 9]),若要將陣列以垂直方向疊合,語法為:
in[1]: np.vstack((A, B))
out[1]: array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
另外還有兩個功能很類似的函式:np.stack、np.hstack,有興趣的同學可以上網搜尋使用說明。
np.meshgrid
功能:將兩個一維陣列交錯組合成二維陣列。
範例
x = np.arange(-2, 3, 1)
y = np.arange(-2, 3, 1)
xv, yv = np.meshgrid(x, y)
print("xv:", xv)
print("yv:", yv)
輸出為
xv: [[-2 -1 0 1 2]
[-2 -1 0 1 2]
[-2 -1 0 1 2]
[-2 -1 0 1 2]
[-2 -1 0 1 2]]
yv: [[-2 -2 -2 -2 -2]
[-1 -1 -1 -1 -1]
[ 0 0 0 0 0]
[ 1 1 1 1 1]
[ 2 2 2 2 2]]
如果將程式碼改為
xx, yy = np.meshgrid(x, y, sparse = True)
print("xx:", xx)
print("yy:", yy)
輸出會變為
xx: [[-2 -1 0 1 2]]
yy: [[-2]
[-1]
[ 0]
[ 1]
[ 2]]
結語
NumPy 內建相當多方便的函式,如果能夠善用這些函式,可以大幅提升程式運作的效率。
HackMD 版本連結:https://hackmd.io/s/BytGou11E
沒有留言:
張貼留言