終於講到這個主題了~ 相信大家都看過 Numpy 這個模組,但是應該都不是很熟悉(沒關係,大鳥大學的時候完全不會寫 Python)。Numpy 基本上是 Python 在做一些所謂 Data Science 運算的核心模組,它對於做高緯度(>3D)的陣列/矩陣運算非常便利。好,進入主題...

環境安裝

Python 裡沒有預設安裝 numpy 的模組。因此在開始寫之前,我們需要安裝這個模組;否則將出現以下錯誤訊息。

>>> import numpy as np
Traceback (most recent call last):
  File "", line 1, in 
ModuleNotFoundError: No module named 'numpy'

各位可以到你們的指令介面直接下這個指令。

pip install numpy

numpy.array()

很有趣的一件事情是,雖然 Python 把陣列稱為 list,Numpy 還是把它稱為 array。我們先來講一下一些在敘述 numpy array 常用到的名詞。

  • Rank: 維度(Dimension)
  • Shape: 一個用來形容 Array 裡每個維度大小的 Tuple

首先,就是要 import numpy 的模組;我們通常都會把它 alias 為 np。我們可以直接透過 numpy.array() 宣告一個 numpy.ndarray。而我們可以透過一些 numpy.ndarray 物件裡的一些 method 來獲取一些資訊。

import numpy as np
# 宣告一個 Numpy Array
a = np.array([1,2,3,4,5])               # rank 1 array / 1d array (size = (1,5))
b = np.array([[1,2,3],[4,5,6]])         # rank 2 array / 2d array / matrix (size=(2,3))
c = np.array([[[1,2],[3,4]],            # rank 3 array / 3d array (size = (2,2,2))
              [[5,6],[7,8]]])
print(type(a))                          # 
print(b.ndim)                           # 2
print(c.shape)                          # (2, 2, 2)

基本上我們人類在思考維度的時候,最多大概只能想像 3-4 維的時空。然而,我們在做深度學習的時候需要碰到更高維度(5、10、50 甚至上萬)。這時候 numpy 的這些 method 會很常派上用場。但是,今天只是在介紹 numpy 入門,我們還不是資料科學家,因此這篇文章不會提到高過三維的陣列;你們只要能夠大概想像多維度陣列大概會是這樣就好了...

當然,numpy 還有一些很便利的 method 可以用來呼叫一些特殊的矩陣哦~大家就自己玩玩看吧~

import numpy as np
a = np.zeros((2,2))
b = np.ones((1,2))
c = np.full((2,2), 7)
d = np.identity(3)
e = np.random.random((2,2))
f = np.arange(4,7)

Indexing,Slicing

如果我們想要獲取某一筆資料的值,基本上就跟普通的陣列一樣,我們可以對它的 index 獲取它的值。我們也可以對它做 slicing,把一塊資料取出來,變成另外一個陣列。

import numpy as np
arr = np.array([[11, 22, 33],
                [44, 55, 66],
                [77, 88, 99]])
print(arr[1,1])         # 55
print(arr[1][1])        # 55
print(arr[1:,:1])       # [[44],[77]]
print(arr[::1][1::])    # [[44 55 66],[77 88 99]]

np.reshape

如果我們想要對一個陣列做一些轉變,我們可以用 resize 來改變它的形狀;當然,是要在不影響陣列矩陣裡面的值為前提。這裡比較會亂的應該是 reshaperesize 兩個 method;這兩個不同的地方在於 reshape 只是在 stdout 輸出一個暫時的矩陣,而 resize 所回傳的是已經經過轉變的矩陣(resize 可以把矩陣的 shape 變大哦~)。transpose 是對矩陣裡的 row 和 column 顛倒。

import numpy as np
arr = np.array([[11, 22],
                [33, 44],
                [55, 66]])
print(arr.shape)         # (3,2)
print(arr.reshape(2,3))  # output temporary array reshape
print(arr.resize(3,4))   # changes the array shape
print(arr.transpose)     # (3,4) -> (4,3)
print(arr.resize(12,1))  # (4,3) -> (12,1)

np.add np.multiply np.dot

最後,我們來對這些矩陣做運算。這裡就要回到各位的高中數學啦(這句話是不是很熟悉?)當我們在做 add 的時候,如果矩陣大小不同的話,他會對陣列裡所有的值做運算,這叫做 broadcasting。要注意的事,就是如果矩陣的形不符合 broadcasting 的需求,就會跳出錯誤訊息。對 numpy array 做 + 運算也是可以哦~

import numpy as np
a = np.array([2])
b = np.array([1,2,3])
c = numpy.add(a,b)
print(c)                # [3,4,5]
d = np.array([[1,2,3],[1,2,3]])
e = c + d
print(e)                # [[4 6 8] [4 6 8]]
f = np.array([[1,2],[1,2]])
g = c + f
# ValueError: operands could not be broadcast together with shapes (3,) (2,2)

numpy.multiplynumpy.dot 是不一樣的東西。multiply 基本上是對 array 裡的所有值做一個 element-wise 的運算;換句話說如果我們有兩個矩陣 M,N 各 shape 為 (2,3),它會在對應的值做乘法,或者如果不同大小,就會做 broadcast。而 numpy.dot 則是對陣列做內積。若所輸入的矩陣 M,N 的 shape 為 (2,3) 和 (3,2),其輸出的值會為 (2,2)。

import numpy as np
a = np.array([1,2,3])
b = np.array([[1,2,3], [4,5,6]])
print(a*b)
# [[ 1  4  9]
#  [ 4 10 18]]
c = np.array([[1, 2, 3], [4, 5, 6]])
d = np.array([[1, 2], [3, 4], [5, 6]])
print(np.dot(c,d))
# [[22 28]
#  [49 64]]

這裡有提供給那些跟大鳥一樣數學很爛的人內積的運算式哦~感謝球哥大大幫忙開導 XDD

Leave a Reply

Your email address will not be published. Required fields are marked *