NumPy 的各種用法 - 讀書筆記 - Python Data Science Handbook - Python數據科學 - NumPy Array的屬性與操作(串聯與切割 - Concatenate、hstack、vstack、split、vsplit、 hsplit) - NumPy Array的各種計算方法 - UFuncs - #5

為自己Coding
·
·
IPFS
·
NumPy Array的屬性與操作(串聯與切割 - Concatenate、hstack、vstack、split、vsplit、 hsplit) - NumPy Array的各種計算方法 - UFuncs

Github連結

攝影師:Markus Spiske,連結:Pexels



2.2章 NumPy數組基礎


1. 重要觀念:

  • Python中的數據處理幾乎與NumPy Array操作是同義詞
  • Pandas也是由NumPy数组構建的



2. NumPy數組操作的基本種類:

  • 數的屬性:決定數組的大小、形狀、內存占用量、數據類型
  • 數組的索引:獲取與設定個別數組元素的值
  • 數組的切片:獲取與設定數組中的子數組
  • 數組的變形: 改變數组的形狀
  • 組合與切分數組多: 將多個個數组合成一個數組,將一個數組切成多個數組



3. NumPy數組的屬性(Attributes)


創建一維、二維、三維數組

import numpy as np
​
## 設定隨機數種子,目的是設定一樣的話,隨機出來的數字组合才會一樣
​
np.random.seed(1)
​
## 創建一维、二维、三維的數組,並用隨機產生器生成數據
d1 = np.random.randint(10, size = 10)
​
d2 = np.random.randint(10, size = (5,5))
​
d3 = np.random.randint(10, size = (2,4,6))
​
​
print(d1)
print(d2)
print(d3)

執行結果

[5 8 9 5 0 0 1 7 6 9]
[[2 4 5 2 4]
 [2 4 7 7 9]
 [1 7 0 6 9]
 [9 7 6 9 1]
 [0 1 8 8 3]]
[[[9 8 7 3 6 5]
 [1 9 3 4 8 1]
 [4 0 3 9 2 0]
 [4 9 2 7 7 9]]
​
 [[8 6 9 3 7 7]
 [4 5 9 3 6 8]
 [0 2 7 7 9 7]
 [3 0 8 7 7 1]]]


ndim、shape、size、dtype用法

  • dim: 數組的維度
  • shape: 每個維度的大小
  • size: 數組的大小(長度)
  • dtype:數據類型
  • itemsize:每個數組元素的大小/長度(單位:bytes)
  • nbytes: 數組的總大小(單位 bytes)
## 印出三維數組的各種屬性
print ("d3 維度(ndim): ", d3.ndim) 
print ("d3 每個維度的長度/大小(shape): ", d3.shape)
print ("d3 數組的大小長度(size): ", d3.size)
print ("d3 數組類型(dtype): ", d3.dtype)
​
print ("d3 每個數組元素的大小/長度(bytes): ", d3. itemsize, "bytes")
print ("d3 數組的總大小/長度(bytes): ", d3.nbytes, "bytes")

執行結果

d3 維度(ndim): 3
d3 每個維度的長度/大小(shape): (2, 4, 6)
d3 數組的大小長度(size): 48
d3 數組類型(dtype): int32
d3 每個數組元素的大小/長度(bytes): 4 bytes
d3 數組的總大小/長度(bytes): 192 bytes

一般情況下,我們期望nbytes 等於 itemsize 乘以size ,也就是nbytes = itemsize * size



4. NumPy數組索引(Indexing)

一維數組的索引

print (d1)
## 索引第一個元素
print (d1[0])
## 索引第七個元素
print(dl[6])

執行結果

[5 8 9 5 0 0 1 7 6 9]
5
1

一維數組的反向索引

從數组後面來索引,使用-負號

## 索引最後一個值
print (d1[-1])
## 索引倒數第三個值
print (d1[-3])

執行結果

9
7

多維數組索引

print(d2)
​
## 索引第一個位置
print(d2[0, 0])
​
## 索引第四個元素數組裡的倒數第二個位置
print(d2[3, -2])

執行結果

[[2 4 5 2 4]
 [2 4 7 7 9]
 [1 7 0 6 9]
 [9 7 6 9 1]
 [0 1 8 8 3]]
2
9


修改數組元素值

## 修改第一個位置的值
d2[0, 0] = 66
d2

執行結果

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


容易犯的錯誤

NumPy數組為固定類型的數組,與Python的動態型數組不同,當我們將浮點數類型的數據加入整數型的數組

中,它會自動技轉換成整數

## 整数類型的一维數组中, 修改第一個位置的值為小數
d1[0] = 3.1415926
d1 ## 含自動轉成整數,因為NumPy是固定類型的數组

執行結果

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



5. NumPy數組的切片(Slicing)- 獲得子數組

一維子數組 One-dimensional subarrays

x = np. arange (10)
x

執行結果

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  • 前六個元素
## 前六個元素
x[:6]

執行結果

array([0, 1, 2, 3, 4, 5])
  • 從第五個到最後一個的元素
## 從第五個到最後一個的元素
x[4:-1]

執行結果

array([4, 5, 6, 7, 8])
  • 從第三個到第八個的元素
## 從第三個到第八個的元素
x[2:8]

執行結果

array([2, 3, 4, 5, 6, 7])
  • 每隔幾個取元素
## 每隔一個取元素
print (x[::2])
## 每隔三個取元素
x[::3]

執行結果

[0 2 4 6 8]
array([0, 3, 6, 9])
  • 每隔一個取元素,並從序號3(第四個)開始
## 每隔一個取元素,並從序號3(第四個)開始
x[3::2]

執行結果

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

一維子數組 One-dimentional subarrays的反向排序

##反向排序
x[::-1]

執行結果

array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
## 從序號6(第七個)開始向前取元素,每隔一個取元素
print (x[6::-2])
## 從序號8(第9個)開始向前取元素,每隔兩個取元素
x[8::-3]

執行結果

[6 4 2 0]

Out[35]:

array([8, 5, 2])


多维子數組 Multi-dimentional subarrays

  • 多维切割與一维是一樣的方式,只是加了逗號來分隔多個切劃
d2

執行結果

array([[66, 4, 5, 2, 4],
   [ 2, 4, 7, 7, 9],
   [ 1, 7, 0, 6, 9],
   [ 9, 7, 6, 9, 1],
   [ 0, 1, 8, 8, 3]])
  • 行的維度取前兩個,列的維度取前四個
## 行的維度取前兩個,列的維度取前四個
d2[:2, :4]

執行結果

array([[66, 4, 5, 2],
   [ 2, 4, 7, 7]])
  • 行的维度取四個,列的維度每隔一個取元素
## 行的维度取四個,列的維度每隔一個取元素
d2 [:4, ::2]

執行結果

array([[66, 5, 4],
   [ 2, 7, 9],
   [ 1, 0, 9],
   [ 9, 6, 1]])
  • 二维數組的反向排序,多維數組為一樣的概念,以此類推
## 二维數組的反向排序,多維數組為一樣的概念,以此類推
d2 [::-1, :-1]

執行結果

array([[ 0, 1, 8, 8],
   [ 9, 7, 6, 9],
   [ 1, 7, 0, 6],
   [ 2, 4, 7, 7],
   [66, 4, 5, 2]])
  • 獲取數組的第幾列
## 獲取數組的第一列
print(d2[:, 0])
​
## 獲取數組的第四列
print (d2[:, 3])

執行結果

[66 2 1 9 0]
[2 7 6 9 8]
  • 獲取數組的第幾行
## 獲取數組的第一行
print(d2[0, :])
​
## 獲取數組的第二行
print(d2[1, :1])

執行結果

[66 4 5 2 4]
[2]
  • 獲取行的另一種寫法
## 獲取行的另一種寫法: 像是第二行 d2[1] 等同於d2[1,:]
print(d2[1])

執行結果

[2 4 7 7 9]



子數組是屬於非複製的視圖 Subarrays as no-copy views

重要概念:

  • Python列表的切片(list slicing)返回的是副本,也就是複製品,但是NumPy數組的切片返回的是子數组的視圖(view)而不是副本(複製品),這也是兩者的重要差異
  • 應用:如果我們對NumPy數組切割後的子數組進行修改,它會同時修改到整個數組
  • 這個方法非常有用,當我們要對大數據集進行處理時,可以對其中的子數據集進行處理就好,不用到內存中再複製一份數據集出來

舉個例子:我個有一個二维數組

d2

執行結果

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

我們切割出來一個3x3的子數組

d2_sub = d2[:3, :3]
d2_sub

執行結果

array([[66, 4, 5],
   [ 2, 4, 7],
   [ 1, 7, 0]])

對子數組進行修改

d2_sub[0,0] = 58
d2_sub

執行結果

array([[58, 4, 5],
   [ 2, 4, 7],
   [ 1, 7, 0]])

發現原本的二维數組也跟著修改了

d2

執行結果

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


創建子數組的副本(複製品)方法

有時候我們不希望修改子數組會影響到整個數組,這時候就需要複製方法

d2

執行結果

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

複製一個子數組出來

## 複製一個子數組出來
d2_sub_copy = d2[:3, :3].copy()
d2_sub_copy[0, 0] = 60
d2

執行結果

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



6. 改變數組的大小與維度 Reshaping of Arrays


兩種方法: reshape和newaxis

## 將一個1到9的數組,轉為3x3的二维數組
array = np.arange(1,10)
array_new2 = array.reshape(3,3)
​
array_new2

執行結果

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

將一個1到27的數組,轉為3x3x3的三維數組

## 將一個1到27的數組,轉為3x3x3的三維數組
array = np.arange(1,28)
array_new = array.reshape(3,3,3)
array_new

執行結果

array([[[ 1, 2, 3],
   [ 4, 5, 6],
   [ 7, 8, 9]],
​
   [[10, 11, 12],
   [13, 14, 15],
   [16, 17, 18]],
​
   [[19, 20, 21],
   [22, 23, 24],
   [25, 26, 27]]])

reshape方法 - 行向量

## reshape方法 - 行向量
X= np.array([1,2,3,4,5,6])
x.reshape(1,6)

執行結果

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

reshape方法 - 列向量

## reshape方法 - 列向量
x = np.array([1,2,3,4,5,6])
x.reshape(6,1)

執行結果

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

newaxis方法 - 行向量

## newaxis方法 - 行向量
x = np.array([1,2,3,4,5,6])
x[np.newaxis, :]

執行結果

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

newaxis方法 - 列向量

## newaxis方法 - 列向量
x = np.array([1,2,3,4,5,6])
x[:, np.newaxis]

執行結果

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



7. 數組的串聯與分割 Array Concatenation and Splitting


Concatenate 串聯

串聯兩個Array

x = np.array([1,2,3,4])
y = np.array([5,6,7,8,9,10])
​
## 串聯兩個數組
np.concatenate([x, y])

執行結果

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


串聯多個Array

z = np.array([6,12,18,28])
## 串聯三個數組
np.concatenate([x,z,y])

執行結果

array([ 1, 2, 3, 4, 6, 12, 18, 28, 5, 6, 7, 8, 9, 10])


串聯兩個二維Array(根據第一個軸) -直的串聯

d2 = np. array([[1,2,3,4], [5,6,7,8]])
## 串聯兩個二維數組,並根據的第一個軸串聯
np.concatenate([d2, d2])

執行結果

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


串聯二維Array(根據第二個軸)- 橫的串聯

np.concatenate([d2, d2], axis = 1)

執行結果

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


hstack & vstack 水平與垂直串聯

垂直串聯 vstack

x = np.array([1,2,3,4])
d2 = np.array([[5,6,7,8], [28,58,66,66]])
​
## 垂直串聯
np.vstack([x, d2])

執行結果

array([[ 1, 2, 3, 4],
   [ 5, 6, 7, 8],
   [28, 58, 66, 66]])


水平串聯hstack

y = np.array([[180], [360]])
​
## 水平串聯數組
np.hstack ([d2, y])

執行結果

array([[ 5, 6, 7, 8, 180],
   [ 28, 58, 66, 66, 360]])


補充: np.distack 用來串聯第三軸



split分割

split

x = [1,2,3,4,66,66,5,6,7]
​
## 根據第五個到第六個位置切成一組,並將其左右邊各切成兩組(x1,x2,x3)
x1, x2, x3 = np.split(x, [4,6]) 
print (x1, x2, x3)

執行結果

[1 2 3 4] [66 66] [5 6 7]


vsplit & hsplit 分割

## 創建5x5的組
d = np.arange (25).reshape(5,5)
d

執行結果

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]])


vsplit

## 垂直分割 - 根據第3行進行分割
upper, lower = np.vsplit(d, [2])
print (upper)
print (lower)

執行結果

[[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]]


hsplit

## 水平分割 - 根據第四列進行分割
left, right = np.hsplit(d, [3])
print(left)
print (right)

執行結果

[[ 0 1 2]
 [ 5 6 7]
 [10 11 12]
 [15 16 17]
 [20 21 22]]
[[ 3 4]
 [ 8 9]
 [13 14]
 [18 19]
 [23 24]]


補充:np.dsplit會根據第三軸分割數組


CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!

為自己CodingYO~~ 剛跨入AI人工智慧領域的小小工程師, 熱愛自學, 熱愛分享, 下班後的我想為自己Coding, 積極撰寫教學文, 想將自學的程式知識分享給大家, 不斷追求進步的自己, 希望有一天能回饋社會,幫助需要幫助的人, 如果您有什麼很酷的想法,也覺得我還行,歡迎您找我合作~~ IG: https://www.instagram.com/coding_4_me/
  • 来自作者
  • 相关推荐

[Takeaways]原力效應 — Part1

[行銷5.0] 人工智慧的緣起

[Aptos學習筆記#8]Move進階使用 - Resource介紹一