NumPy 101:資料科學的基石

NumPy is the fundamental package for scientific computing with Python.——numpy.org

摘要

NumPy(Numerical Python)套件是 Python 資料科學的基石,利用 ndarray類別作為同質資料數列儲存與運算的依據,實踐其他科學計算語言(R、Matlab 與 Julia)的向量化功能,在這個小節中包含了簡介、描述她所因應的痛點以及如何創建。


關於 NumPy

NumPy,是 Numerical Python 的縮寫,是 Python 使用者用來實踐向量化(Vectorization)、科學計算與資料科學的套件,資料科學團隊使用她所提供一種稱為 ndarray 的資料結構來儲存並運算數值陣列、與標準函式庫 random 相輔相成的 numpy.random 來處理隨機性以及 numpy.linalg 來處理線性代數中一些繁複的運算。


透過 ndarray 的數值陣列幾乎能夠面對任意的資料來源,包括實驗數據、圖像(表示像素亮度的二維數值陣列)或者音訊(表示強度與時間軸的一維數值陣列。)


熟悉 ndarray 的操作對於以 Python 應用資料科學的使用者來說是必要的前提,她也扮演著理解機器學習理論的基石,如果能夠自信地操作二維數值陣列(即矩陣 Matrix)以及三維數值陣列(即張量 Tensor),將更容易理解高階機器學習框架究竟在封裝起來的函數、方法中提供了哪些功能給使用者,進而更有效率作超參數的調校。


起步走

執行 Python 的載入指令確認環境中是否安裝了 NumPy 可供使用。


如果安裝妥當,應該可以得到回應:

## 1.16.4

假若得到的回應是:

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ModuleNotFoundError: No module named 'numpy'

表示目前所處的 Python 環境沒有安裝 NumPy,在命令列中輸入 pip install --user numpy 即可完成安裝。


pip install --user numpy


在 Jupyter Notebook 或 Google Colab 中以 np.<TAB> 與 np? 可以獲得函數名稱提示以及說明文件幫助。


以 np.<TAB> 與 np? 獲得函數名稱提示以及說明文件幫助

痛點

模組、套件或函式庫的開發多半起源於某些痛點,就像創新產品的問世一般,那麼具體來說,Python 的 list 的什麼特性讓科學計算使用者覺得有些麻煩呢?就是 list 具備儲存異質資料型態的特性:


heterogeneous_list = [5566, 55.66, True, False, '5566']
for i in heterogeneous_list: print(type(i))

## <class 'int'>

## <class 'float'>

## <class 'bool'>

## <class 'bool'>

## <class 'str'>

list 中每個元素都是一個完整的 Python 物件,具備各自的類別與數值資訊,這讓她在計算同質資料時的效能、語法付出代價,我們需要透過迭代(iteration)將裡面的物件一一取出後運算。

## [1, 4, 9, 16, 25]

NumPy 的 ndarraylist 的最大不同在於她同質資料型態的特性,在計算時的效能和語法更快速與簡潔。


import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr**2)

## [ 1  4  9 16 25]

list 在處理數值資料上的劣勢在多維陣列運算上會被更加凸顯,例如以巢狀的 list 來表示矩陣,進行矩陣的內積就必須寫作三層的巢狀迴圈。


A = [ [1, 2], [3, 4]
]
B = [ [5, 6], [7, 8]
]
AB = [ [0, 0], [0, 0]
]
I = len(A)
K = len(A[0])
J = len(B[0])
for i in range(I): for k in range(K): for j in range(J): AB[i][j] += A[i][k] * B[k][j]
print(AB)

## [[19, 22], [43, 50]]

ndarray 則可以使用預先定義好的方法或運算符進行矩陣內積。


import numpy as np
A = np.array([ [1, 2], [3, 4]
])
B = np.array([ [5, 6], [7, 8]
])
AB = A@B # AB = np.dot(A, B); AB = A.dot(B)
print(AB)

## [[19 22]

##  [43 50]]

至此,關於 ndarray 在同質數值陣列計算的便利性已經不需要再贅述,接著我們暸解如何創建 ndarray 以及 NumPy 的標準資料型態。

創建 ndarray

創建 ndarray 的方法有二種:一是使用 np.array() 函數由既有的 list 轉換而成。


import numpy as np
homogeneous_list = [1, 2, 3, 4, 5]
print(type(homogeneous_list))
arr = np.array(homogeneous_list)
print(type(arr))
print(arr)
print(arr.dtype)

## <class 'list'>

## <class 'numpy.ndarray'>

## [1 2 3 4 5]

## int64

np.array() 函數可以搭配 dtype 參數指定資料型態,可以傳入下列常見的資料型態:


  • int :可指定 8 到 64 位元的整數型態

  • float :可指定 16 到 64 位元的浮點數型態

  • bool :布林型態


import numpy as np
homogeneous_list = [1, 2, 3, 4, 5]
arr = np.array(homogeneous_list, dtype=int)
print(arr.dtype)
arr = np.array(homogeneous_list, dtype=float)
print(arr.dtype)


## int64

## float64


二是使用多樣式的 NumPy 函數直接創建,同樣可以搭配 dtype 參數,常用的 ndarray 創建函數有:


  • np.zeros(shape) :創建指定外觀充滿 0 的數值陣列


import numpy as np
np.zeros(5, dtype=int)

## array([0, 0, 0, 0, 0])


  • np.ones(shape) :創建指定外觀充滿 1 的數值陣列


import numpy as np
np.ones((2, 2), dtype=float)

## array([[1., 1.],

##        [1., 1.]])


  • np.full(shape, fill_value) :創建指定外觀充滿 fill_value 的數值陣列


import numpy as np
np.full((2, 2), 5566, dtype=int)

## array([[5566, 5566],

##        [5566, 5566]])


  • np.arange(start, stop, step) :創建從 start (包含)間隔 step 至 stop (不包含)的等差數列,使用方式同內建函數 range()


import numpy as np
np.arange(1, 10, 2)

## array([1, 3, 5, 7, 9])


  • np.linspace(start, stop, num) :創建從 start (包含)至 stop (包含)的均勻切割為 num 個資料點的數值陣列


import numpy as np
np.linspace(1, 9, 5, dtype=int)

## array([1, 3, 5, 7, 9])


  • np.random.random(size) :創建指定外觀介於 0, 1 之間、並符合均勻分佈的數值陣列


import numpy as np
import matplotlib.pyplot as plt
arr = np.random.random(10000)
plt.hist(arr)
plt.show()


  • np.random.normal(loc, scale, size) :創建指定外觀以 loc 為平均數、 scale 為標準差常態分佈的數值陣列


  • np.random.randint(low, high, size) :創建指定外觀於 low (包含)到 high (不包含)之間隨機抽樣之正整數的數值陣列


import numpy as np
np.random.randint(1, 7, size=6)

## array([2, 6, 3, 1, 4, 6])


截至目前為止,我們已經掌握多種創建 ndarray 的方式,並準備好在後續的小節研究如何對數值陣列做基本的處理、操作及運算。

YOTTA 你最專業的學習夥伴,提供優質內容與有趣觀點,擴大豐富你的視野。




封面圖片來源:freecodecamp