Hello NumPy!
文章搬新家囉!
全新內容歡迎參考 「Hello NumPy!|NumPy 入門詳細介紹 (2023更新版)」及「Python for Beginners 系列文章」,未來最新文章也將移至 Here
想了解 AI 、機器學習及深度學習的基礎概念,【從 AI 到 生成式 AI:40 個零程式的實作體驗,培養新世代人工智慧素養】,將帶領讀者在不會程式、不會數學也OK!的情況下,建立最完整的 AI 入門知識。
歡迎海、內外讀者持續追蹤及關注我們的文章~~
本系列文章希望能讓有興趣學習資料科學(Data Science)及Python程式語言的人,透過全新不同的方式,由淺入深獲得相關知識,除了前一篇的Python初體驗文章,這一篇將帶領大家了解未來進入資訊科學領域前,如何利用NumPy函式庫的強大功能,理解相關的基礎應用。
NumPy Introduction
NumPy是Python在進行科學運算時,一個非常基礎的Package,同時也是非常核心的library,它具有下列幾個重要特色:
- 提供非常高效能的多維陣列(multi-dimensional array)數學函式庫
- 可整合C/C++及Fortran的程式碼
- 方便有用的線性代數(Linear Algebra)及傅立葉轉換(Fourier Transform)能力
- 利用NumPy Array替代Python List
- 可定義任意的數據型態(Data Type),使得能輕易及無縫的與多種資料庫整合
在邁向資料科學(Data Science)、機器學習(Machine Learning)、深度學習(Deep Learning)及人工智慧(Artificial Intelligence)的路上, Python還有許許多多有趣好玩的套件(例如:Pandas、SciPy、Sympy、Matplotlib、Scikit-learn 等),這些與資料科學相關的重要套件幾乎都是架構在 Numpy基礎上做應用,因此學會NumPy對後續的學習及理解將會有很大的幫助。
NumPy Fundamentals
在介紹NumPy基礎操作前,必須先進行import NumPy的動作,才能使用其函式庫內的相關功能,大家可以在Python IDLE中的Shell環境中試著輸入下方式子:
>>> import numpy as np
接下來我們將依序對一些基本及重要的功能逐一介紹。
1.NumPy Array
學習資料科學(Data Science)或機器學習(Machine Learning)時,利用NumPy在陣列的操作是非常重要,其主要功能都架構在多重維度(N-dimensional array)的 ndarray上,ndarray是一個可以裝載相同類型資料的多維容器,維度的大小及資料類型分別由shape及dtype來定義。通常我們會稱一維陣列為向量(vector),二維陣列為矩陣(matrix),未來在機器學習系列文章中會再仔細介紹此一部分。而一維陣列到多維陣列的各軸向(axis)可參考下圖,對於後續學習幫助很大。
[caption id=”attachment_17" align=”alignnone” width=”1698"]
陣列維度(Dimension)及軸向(axis)[/caption]
- 建立陣列及初始值
我們會先import numpy 模組,透過傳入Python的list或tuple到 numpy.array() 建立陣列。
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4]) #一維陣列建立
>>> b = np.array([(2.5, 1, 3, 4.5), (5, 6, 7, 8)], dtype = float) #二維陣列建立
>>> c = np.array([[(2.5, 1, 3, 4.5), (5, 6, 7, 8)], [(2.5, 1, 3, 4.5), (5, 6, 7, 8)]], dtype = float) #三維陣列建立
下面幾種方式除了可以建立陣列外,也可以同時給予初始值
>>> np.zeros((2, 3)) # 建立一個2x3全為0的陣列
>>> np.ones((2, 3, 4)) # 建立一個2x3x4全為1的陣列
>>> np.arange(1, 10, 2) # 建立一個由1開始,不超過10,間隔值為2的均勻數值陣列
>>> np.linspace(0, 10, 5) # 建立一個0到10之間,均勻的5個數值陣列
>>> np.full((3,2), 8) # 建立一個3x2全為8的陣列
>>> np.eye(2) # 建立一個5x5的單位矩陣
>>> np.random.random((2,3)) # 建立一個2x3的隨機值矩陣
2.I/O
>>> import numpy as np
>>> original_array = np.array([1, 2, 3])
>>> np.save('my_array', original_array)
>>> np.savetxt('my_array.txt', original_array)
>>> array_from_npy = np.load('my_array.npy')
>>> print(array_from_npy)
[1 2 3]
>>> array_from_txtfile = np.loadtxt('my_array.txt')
>>> print(array_from_txtfile)
[1. 2. 3.]
3.Data Types
NumPy支援比Python更多的數字類型。可參考下圖。
[caption id=”attachment_19" align=”alignnone” width=”866"]
NumPy Data Type (圖片來源:scipy.org)[/caption]
其中有5種基本數字類型比較常用,分別是booleans (bool), integers (int), unsigned integers (uint), floating point (float)和complex。
>>> np.array([1.2, 3, 5.2], dtype='i')
array([1, 3, 5], dtype=int32)
>>> np.array([1, 2, 3], dtype='f')
array([1., 2., 3.], dtype=float32)
>>> x = np.float32(1)
>>> x
1.0
>>> y = np.int_([1.0, 2.3])
>>> y
array([1, 2])
4.Inspecting Your Array
>>> a = np.array([1, 2, 3])
>>> b = np.array([(2.5, 1, 4.5), (5, 6, 7, 8)])
>>> a.shape # Array dimensions
(3,)
>>> len(a) # Length of array
3
>>> len(b) # Length of array
2
>>> b.ndim # Number of array dimensions
1
>>> a.size # Number of array elements
3
>>> b.size # Number of array elements
2
>>> b.dtype # Data type of array elements
dtype('O')
>>> a.dtype # Data type of array elements
dtype('int32')
>>> b.dtype.name # Name of data type
'object'
>>> a.dtype.name # Name of data type
'int32'
>>> a.astype(float) # Convert an array to a different type
array([1., 2., 3.])
5.Asking For Help
>>> np.info(max)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
>>> np.info(np.ndarray.dtype)
Data-type of the array's elements.
Parameters
----------
None
Returns
-------
d : numpy dtype object
See Also
--------
numpy.dtype
Examples
--------
>>> x
array([[0, 1],
[2, 3]])
>>> x.dtype
dtype('int32')
>>> type(x.dtype)
<type 'numpy.dtype'>
6.Array Mathematics
- Arithmetic Operations
>>> a = np.array([1, 2, 3])
>>> b = np.array([2, 4, 6])
>>> np.add(a, b) # 陣列加法,也可以a + b
array([3, 6, 9])
>>> np.subtract(a, b) # 陣列減法,也可以a – b
Array([-1, -2, -3])
>>> np.multiply(a, b) # 陣列乘法,也可以a * b
Array([ 2, 8, 18])
>>> np.divide(a, b) # 陣列除法,也可以a / b
array([0.5, 0.5, 0.5])
除了四則運算之外,也可以對陣列做其他的算術運算
>>> c = np.array([1, 4, 9])
>>> np.sqrt(c)
array([1., 2., 3.])
>>> np.sin(c)
array([ 0.84147098, -0.7568025 , 0.41211849])
>>> np.cos(c)
array([ 0.54030231, -0.65364362, -0.91113026])
>>> np.log(c)
array([0. , 1.38629436, 2.19722458])
- Comparison
NumPy也提供Array幾種比較方式如下:
>>> a = np.array([(1, 2, 3), (4, 5, 6)])
>>> b = np.array([(1, 3, 3), (4, 7, 6)])
>>> c = np.array([(1, 2, 3), (4, 5, 6)])
>>> a == b # Element-wise comparison
array([[ True, False, True],
[ True, False, True]])
>>> a < 3 # Element-wise comparison
array([[ True, True, False],
[False, False, False]])
>>> np.array_equal(a, b) # Array-wise comparison
False
- Aggregate Functions
利用numpy的聚合函數(Aggregate Functions)於統計領域是很方便的,常見聚合函數有最大值(max)、最小值(min)、中位數( median)、平均數(mean)、方差、標準差(std)、在numpy的使用上是很常見的。
>>> a = np.array([2, 5, 7])
>>> b = np.array([(0, 1), (2, 3)])
>>> a.sum() # Array-wise sum
14
>>> a.max() # Array-wise maximum value
7
>>> a.min() # Array-wise minimum value
2
>>> b.max(axis=0) # Maximum value of an array row
array([2, 3])
>>> b.max(axis=1) # Maximum value of an array row
array([1, 3])
>>> np.median(a) # Median
5.0
>>> np.mean(a) # Mean
4.666666666666667
>>> np.std(a) # Standard deviation
2.0548046676563256
7.Copying & Sorting Arrays
numpy同時提供多種陣列間的copying及sorting功能,我們就先簡介其中幾種做法。
>>> a = np.array([5, 13, -5, -2, 3, 4, 7])
>>> a.sort()
>>> a
array([-5, -2, 3, 4, 5, 7, 13])
>>> b = np.copy(a)
>>> b
array([-5, -2, 3, 4, 5, 7, 13])
8.Subsetting, Slicing, Indexing
藉由下列範例你將會清楚了解Subsetting, Slicing及Indexing的應用。我們先試著各建立一個一維陣列(1D array)及二維陣列(2D array)如下:
>>> a = np.array([1, 2, 3, 4])
>>> b = np.array([(2.5, 1, 3, 4.5), (5, 6, 7, 8)])
- Subsetting
>>> a[2]
3
>>> b[1, 3]
>>> 8.0
- Slicing
>>> a[0 : 2]
array([1, 2])
>>> b[0 : 2, 1]
array([1., 6.])
>>> b[1, 0 : 2]
array([5., 6.])
>>> b[ : 1]
array([[2.5, 1. , 3. , 4.5]])
- Boolean Indexing
>>> a[a < 4]
array([1, 2, 3])
- Fancy Indexing
>>> b[[1, 1, 0, 0], [0, 2, 1, 0]]
array([5. , 7. , 1. , 2.5])
9.Array Manipulation
- Transposing Array
>>> a = np.array([(1, 3, 5, 7), (2, 4, 6, 8)])
>>> a
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
>>> b = np.transpose(a)
>>> b
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
>>> b.T
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
- Changing Array Shape
>>> a = np.array([(1, 3, 5, 7), (2, 4, 6, 8)])
>>> a
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
>>> a.shape
(2, 4)
>>> a.ravel()
array([1, 3, 5, 7, 2, 4, 6, 8])
>>> a.reshape(4, 2)
array([[1, 3],
[5, 7],
[2, 4],
[6, 8]])
- Adding/Removing Elements
>>> a = np.array([1, 2, 3, 4]) # 建立a陣列
>>> b = np.array([6, 7, 8, 9]) # 建立b陣列
>>> np.append(a, 5)
array([1, 2, 3, 4, 5])
>>> np.append(a, b)
array([1, 2, 3, 4, 6, 7, 8, 9])
>>> np.insert(a, 1, 0)
array([1, 0, 2, 3, 4])
>>> np.delete(b, [2])
array([6, 7, 9])
>>> a.resize((2,2))
>>> a
array([[1, 2],
[3, 4]])
- Combining Arrays
利用NumPy將array間做彼此合併或連結的方法很多,這裡先簡單介紹一些常用的方式。
- vstack:垂直方向合併
- hstack:水平方向合併
>>> a = np.array([(1, 2), (3, 4)])
>>> b = np.array([(5, 6), (7, 8)])
>>> np.vstack((a, b)) # 垂直方向合併
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
>>> np.hstack((a, b)) # 水平方向合併
array([[1, 2, 5, 6],
[3, 4, 7, 8]])
- concatenate (axis = 0):沿垂直方向合併
- concatenate (axis = 1):沿水平方向合併
>>> np.concatenate((a, b), axis = 0) # axis=0,沿垂直方向合併
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
>>> np.concatenate((a, b), axis = 1) # axis=1,沿水平方向合併
array([[1, 2, 5, 6],
[3, 4, 7, 8]])
- Splitting Arrays
跟Combining Arrays一樣,NumPy提供一些在不同軸向的切割方式,如下說明:
- vsplit:垂直方向分割
- hsplit:水平方向分割
>>> a = np.array([(1, 2, 3, 4, 5, 6), (-1, -2, -3, -4, -5, -6), (2, 4, 6, 8, 10, 12)])
>>> a
array([[ 1, 2, 3, 4, 5, 6],
[-1, -2, -3, -4, -5, -6],
[ 2, 4, 6, 8, 10, 12]])
>>> np.vsplit(a, 3) # 垂直方向分割
[array([[1, 2, 3, 4, 5, 6]]), array([[-1, -2, -3, -4, -5, -6]]), array([[ 2, 4, 6, 8, 10, 12]])]
>>> np.hsplit(a, 2) # 水平方向分割
[array([[ 1, 2, 3],
[-1, -2, -3],
[ 2, 4, 6]]), array([[ 4, 5, 6],
[-4, -5, -6],
[ 8, 10, 12]])]
>>> np.split(a, 3, axis=0) # axis=0,沿垂直方向分割
[array([[1, 2, 3, 4, 5, 6]]), array([[-1, -2, -3, -4, -5, -6]]), array([[ 2, 4, 6, 8, 10, 12]])]
>>> np.split(a, 2, axis=1) # axis=1,沿水平方向分割
[array([[ 1, 2, 3],
[-1, -2, -3],
[ 2, 4, 6]]), array([[ 4, 5, 6],
[-4, -5, -6],
[ 8, 10, 12]])]
後續會再分享 NumPy 相關文章給有興趣的初學者。
讀者若想要多了解一些 Python 的基本程式語法,可以參考 Python for Beginners 系列文章,裡面有大量範例及 Quiz 練習。若是想要了解一些 AI 、機器學習及深度學習的基礎概念,可以參考這一本書【從 AI 到 生成式 AI:40 個零程式的實作體驗,培養新世代人工智慧素養】,它將帶領讀者在不會程式、不會數學也OK!的情況下,建立最完整的 AI 入門知識。
如果你喜歡這篇文章歡迎分享與追蹤,持續關注最新文章。
By Steven Lo (IG:@kwangchih)