NumPy基礎 — 初步理解NumPy Array(陣列)

Sean Yeh
Python Everywhere -from Beginner to Advanced
10 min readDec 18, 2020
Karuizawa, Japan, photo by Sean Yeh

什麼是NumPy?

NumPy 是 Python中有關於線性代數的(Linear Algebra)函式庫,在Python的世界裡是一個很重要的函式庫。當透過Python原生的list來處理龐大資料時,其效能在表現上並不理想。然而NumPy 的底層是以 C 和 Fortran 語言實作,所以能夠快速的操作多維度的陣列。因此NumPy主要被廣泛用於資料處理上,尤其是在資料科學(Data Science)或者是機器學習(Machine Learning)上的應用。

此外,可以說幾乎大部分的Pyhton資料科學處理相關套件(例如:Pandas、SciPy、Scikit-learn 等)都幾乎是奠基在 NumPy 的基礎上建構的。

因此本文從NumPy最基礎的Array開始介紹起,包含Array如何產生以及如何操作等等。

NumPy Array陣列

建立Numpy 陣列之前,先要載入numpy :

import numpy as np

載入之後,我們就可以開始操作。

從Python 的 List建立NumPy陣列

我們可以直接從Python 的 串列(list)轉換為NumPy的陣列。

1D陣列

首先,我們指定 mylist 為 [1,2,3]。

mylist = [1,2,3]

現在如果想要把它從串列變成NumPy陣列的話,可以執行下面的指令:

np.array(mylist)

結果執行後,就會轉換成1D的NumPy 陣列:

array([1, 2, 3])

2D陣列

再來,我們指定mymax為[[1,2,3],[4,5,6],[7,8,9]]。

mymax = [[1,2,3],[4,5,6],[7,8,9]]

並執行下面的指令把它從串列變成NumPy陣列:

np.array(mymax)

結果執行後,就會轉換成2D的NumPy 陣列,可以從最外側『 ] 』的數量得知:

array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])

你可能會問前述的mylist,其資料型態是否受到影響?

這時候可以使用type()來確認mylist一開始的資料型態。

type(mylist)

如果沒意外的話,結果應該是串列(list)。

接著執行np.array把mylist從串列變成NumPy陣列:

np.array(mylist)

這時候再次使用type(mylist)來確認mylist的資料型態:

type(mylist)

結果你會發現,mylist的資料型態仍然是串列(list)。

因此,我們可以得到一個結論,那就是利用np.array()的方法,並不會根本的改變原來的資料型態。

內建(Built-in)方法

以下有些內建的方式一樣可以建立NumPy陣列。

arange

arange()的括弧中,第一個參數是起始值,第二參數個是結束值,如果有第三個參數的話,它是值與值之間的 step差距。

例如:arange()的括弧中,起始值為0,結束值為10。

np.arange(0,10)

NumPy陣列結果如下:

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

與Python一樣結束值10本身不算,產生0到9的數字。

又如 arange()的括弧中,起始值為0,結束值為11,值與值之間的 step為2。

np.arange(0,11,2)

產生NumPy陣列如下:

array([ 0,  2,  4,  6,  8, 10])

陣列為0到10的數字,其中每個數字間的間隔為2。

零與一

如果要產生一組全部為零或者是全部唯一組合而成的NumPy陣列,可以使用np.zeros與np.ones。

Zeros

使用:

np.zeros(3)

可以產生1X3的0的NumPy陣列:

array([0., 0., 0.])

若使用:

np.zeros((4,10))

產生4X10的 0的陣列,其中第一個數字是row、第二個數字是column。

從結果可以發現每個0後面都多出一個點, 它們的性質都是浮點數:

array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

Ones

使用:

np.ones(3)

會產生出 1X3 的1的NumPy陣列:

array([1., 1., 1.])

若使用:

np.ones((4,4))

則會產生出4X4的 1的陣列:

array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])

Linspace等差

linspace 可以用來建立等差數列。linspace函數的前兩個參數分別是數列的開頭與結尾。如果寫入第三個參數,可以決定數列中元素的個數。

例如:

np.linspace(0,10,21)

其結果會產生21個數字,這21個數字平均分佈在0與10之間:

array([ 0. ,0.5, 1. , 1.5, 2. , 2.5, 3. ,3.5, 4. , 4.5, 5. ,        5.5, 6. , 6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5, 10. ])

你可以使用len()檢查看看答案是不是21個數字:

len(np.linspace(0,10,21))

再試試看:

np.linspace(0,10,3)

結果產生3個數字,這3個數字平均分佈在0與10之間。

array([ 0.,  5., 10.])

Eye對角

eye()可以生成對角陣列,例如:

np.eye(5)

產生5X5的1對角陣列:

array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])

Random隨機

透過NumPy產生隨機陣列的方式不限於一種,下面將陸續介紹:

.rand()

例如:

np.random.rand(3)

結果產生3組數值介於0與1之間的隨機陣列:

array([0.92492807, 0.62061755, 0.25761961])

又如:

np.random.rand(3,4)

結果產生3X4,數值介於0與1之間的隨機陣列:

array([[0.14745597, 0.90289823, 0.96513515, 0.96212318],
[0.14563282, 0.94438876, 0.9793023 , 0.42891535],
[0.49834662, 0.81891978, 0.92409685, 0.83018676]])

.randn()

透過randn可以隨機得到一組數字,可能是負的或正的,可能大於或小於一。例如:

np.random.randn(5,5)

結果產生5X5的隨機陣列:

array([
[ 1.43586758, 0.69771937, 0.24893403, -1.80975405, 1.33146942],[-0.70580053, -1.97220917, -1.16640362, 0.20484056, -1.13146332],
[ 0.89121445, -0.74409742, -0.65916333, -0.4009693 , 0.32148039],[-1.41860963, 0.01402724, 0.80222814, 1.23859014, 0.09027154],[-0.94337373, -0.03859034, 0.42829056, -0.97693682, 1.07027364]])

.randint()

使用.randint()可以產生隨機數字,它有參數(low, high,size)可以自己設定範圍。該數字落在兩個數字區間中。

例如:

np.random.randint(1,100)

結果產生一個隨機數字,該數字的值會落在1與100之間。

66

又如下面:

np.random.randint(1,100,10)

結果產生10個隨機數字,該數字的值皆落在1與100之間。

array([70, 52, 17, 80, 38, 39,  2, 14, 83, 19])

又如下面:

np.random.randint(1,100,(2,3))

結果產生:

array([[40, 29, 30],
[67, 4, 63]])

NumPy Array的屬性與方法

首先回顧一下前面所述:

如果我們要建立的是一般的NumPy Array,可以使用下面方式:

arr= np.arange(25)

執行結果就會產生一組0到24的1D陣列:

array([ 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])

若我們想要產生的就是隨機的數字。則需要使用random來產生,下面的NumPy Array裡面有10個隨機數字,每個數字的大小介於從0到50之間。

ranrr = np.random.randint(0,50,10)

執行結果產生:

array([38, 18, 22, 10, 10, 23, 35, 39, 23,  2])

下面介紹幾個有用的屬性與方法:

Shape與Reshape

承上敘述,假定 arr= np.arange(25)

我們可以使用shape屬性來看看這個NumPy Array的形狀。

arr.shape

結果顯示:

(25,)

這代表有一行25個數字的1D NumPy Array。

如果想要改變NumPy Array的排列方式,我們可以使用reshape的方法。reshape方法可以用來改變NumPy Array的shape:

下面就是把原來的一行25個數字的矩陣改為5行每行5個數字的矩陣。

arr.reshape(5,5)

執行結果顯示:

array([[ 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]])

然而,這樣的改變,並沒有終極的改變NumPy Array的排列狀態。因此,若我們重新呼叫arr的話,

結果仍然會顯示原來的矩陣。

array([ 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])

然而,若一定要終極改變NumPy Array排列的話。可以透過指定一個變數給它:

arr = arr.reshape(5,5)

指定arr給它,印出來的arr就變成5X5的NumPy Array了。

array([[ 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]])

max, min 最大與最小

透過 max與 min可以找到陣列裡面的最大值與最小值。

假設目前 ranarr的結果為:

array([38, 18, 22, 10, 10, 23, 35, 39, 23,  2])

如果使用:

ranrr.max()

會產生39的結果。因為ranarr的最大值是39。

而若使用:

ranrr.min()

則會產生2。因為ranarr之最小值為2。

argmax, argmin

承上面的ranarr,使用argmin或者是argmax,則可以找到陣列中最大值與最小值所在的位置。

ranrr.argmax()

結果為:7。最大值39的位置在7(從0開始起算)的地方。

ranarr.argmin()

則其結果為:9。最小值2的位置在9(從0開始起算)的地方。

dtype

會顯示資料的類型。例如:

ranrr.dtype

會得到:dtype(‘int64’)

以上是關於NumPy Array的基礎。後面將繼續討論NumPy的其他概念。

--

--

Sean Yeh
Python Everywhere -from Beginner to Advanced

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。