NumPy 的各種用法 - 讀書筆記 - Python Data Science Handbook - Python數據科學 - NumPy Array的屬性與操作(串聯與切割 - Concatenate、hstack、vstack、split、vsplit、 hsplit) - NumPy Array的各種計算方法 - UFuncs - #5
IPFS
Github連結
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會根據第三軸分割數組
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
- 来自作者
- 相关推荐