回顧
在資料處理利器NumPy初識(一)中,我們介紹了NumPy的基本概念、基礎資料結構以及NumPy數組,也就是ndarray的幾種常見建立方法。今天我們介紹一下NumPy的幾個常用函數和ndarray的索引與切片。
NumPy常用函數
NumPy中有很多用于處理ndarray資料的函數,常用的包括reshape()、resize()、copy()、astype()、stack()、split()等,下面我們分别來看一下這幾個函數的功能和用法。
- 改變數組形狀:reshape()、resize()、T
reshape()函數的作用是重新調整ndarray的行數、列數、維數,根據傳入的參數個數不同,可以重置成不同維數的數組,但是新的形狀必須與原來的形狀相容,即相乘後必須等于原數組中元素的總數量,否則會報錯。基本用法如下。
import numpy as nparr1 = np.arange(12)print(arr1)print("---------------")arr2 = arr1.reshape(3, 2, 2)print(arr2)print("---------------")arr3 = arr2.reshape(3, 4)print(arr3)
以上代碼首先建立了一個一維ndarray,共12個數,然後使用reshape()函數将一維ndarray調整成3*2*2的三維ndarray,再對新的三維ndarray調整成3*4的二維ndarray,可以看到,不管做怎樣的調整,相乘後的結果都是源數組的元素總個數12。運作結果如下所示。

reshape()函數
resize()函數與reshape()函數的作用一樣,也可以重新調整ndarray的行數、列數、維數,不同的是reshape()函數需要相容原來的形狀,少于或超出原數組個數會報錯,而resize()函數不會報錯,當少于時,resize()函數會自動截斷,當超出時,resize()函數會循環copy原數組中的值進行填充,直至将新ndarray填充滿。我們建立一個10個數的一維ndarray,将形狀調整成3*4共12個數,代碼如下。
import numpy as nparr = np.arange(10)print(arr)print("---------------")np.resize(arr, (3, 4)) # 數量不夠時會循環使用直至充滿形狀print(np.resize(arr, (2, 6)))print("---------------")print(arr.resize(2, 6))print(arr)
運作結果如下所示,新數組共3*4=12個數,大于原數組的10個數,多出的兩個數就會從原數組中取出前兩個數進行填充。另外,調用ndarray本身的resize()方法不會生成新ndarray,但會改變ndarray形狀,調用後再次列印arr,會發現它的形狀已經被改變了,并且多餘的位置以0填充。
resize()函數
T的作用是轉置, 對二維ndarray來說,就是交換行列,需要注意的是T并不是函數,後面不要加括号。
import numpy as nparr1 = np.arange(12).reshape(3, 4)print(arr1)print("---------------")arr2 = arr1.Tprint(arr2)
運作結果如下所示。
轉置T
- ndarray複制:copy()
ndarray的複制使用NumPy的copy()函數,當我們把一個ndarray複制給新的ndarray時,兩者是緊密關聯的,當原ndarray改變時,新ndarray也會随之改變,但一般我們使用複制并不想要他們有關聯性,這個時候使用copy()函數就可以解決這個問題,其實這就是NumPy中的淺copy和深copy。下面我們看一下兩者的差別。
import numpy as nparr1 = np.arange(10)arr2 = arr1 # 指向同一個數組print(arr1 == arr2)arr1[2] = 100print(arr1)print(arr2)print("---------------")arr3 = arr1.copy()print(arr1 == arr3)arr1[3] = 1000print(arr1)print(arr3)
運作結果如下圖所示。首先不管是指派還是使用copy()函數生成新ndarray,兩者的值都是相等的。差別就是改變原數組時,一個會随之改變,一個不會。
copy()函數
- ndarray資料類型轉換:astype()
NumPy中支援的資料類型比Python内置的類型要更多,下表列舉了常用的NumPy基本資料類型。
常見NumPy資料類型
NumPy中設定ndarray資料類型使用astype()函數,基本用法如下。
import numpy as nparr1 = np.arange(10, dtype=float)print(arr1, arr1.dtype)arr2 = arr1.astype(np.int64)print(arr2, arr2.dtype)arr3 = arr2.astype(np.string_)print(arr3, arr3.dtype)
運作結果如下所示。
astype()函數
- ndarray合并:stack()
ndarray的合并使用NumPy的stack()函數,傳入要合并的ndarray,axis參數表示按行合并或按列合并,預設axis=0按行合并,axis=1時按列合并。按行合并或按列合并還可以使用hstack()函數或vstack()函數。基本用法如下。
import numpy as npa = np.arange(5)b = np.arange(5, 9)print(a)print(b)print("---------------")print(np.hstack((a, b, a))) # 橫向連接配接print("---------------")c = np.array([[1], [2], [3]])d = np.array([['a'], ['b'], ['c']])print(c)print(d)print("---------------")print(np.vstack((c, d))) # 縱向連接配接print("---------------")# 預設縱向# print(np.stack((a, b), axis=1)) # 列數不一緻,會報錯b = np.arange(5, 10)print(np.stack((a, b, a), axis=1))
運作結果如下。需要注意的是,在合并時,必須保證要合并的幾個ndarray在合并方向上的數量是一緻的,否則會報錯。
stack()函數
- ndarray拆分:split()
NumPy中使用split()函數對ndarray進行拆分,與合并的stack()函數類似,axis表示拆分方向,同時,也有hsplit()函數和vsplit()函數分别按行或按列拆分。split()相關函數的基本用法如下。
import numpy as nparr = np.arange(16).reshape(4, 4)print(arr)print("---------------")print(np.hsplit(arr, 2))print(np.split(arr, 2, axis=1))print("---------------")print(np.vsplit(arr, 2))print(np.split(arr, 2))
運作結果如下。拆分時必須保證拆分的數量能等分,否則會報錯。
split()函數
NumPy的索引和切片
NumPy中的索引和切片的運用包括基本索引和切片以及布爾型索引和切片。
- 基本索引和切片
NumPy中ndarray的基本索引和切片與Python中的數組類似,我們分别以一維、二維、三維ndarray作為代表看一下NumPy中ndarray的基本索引和切片。
1、一維ndarray的基本索引和切片
import numpy as nparr = np.arange(10)print(arr)print("---------------")# 直接索引,列印arr索引為2的值print(arr[2])print("---------------")# 切片,列印arr中從索引5開始到最後一個數的值(包括5)print(arr[5:])print("---------------")print("---------------")# 切片,列印arr中從開始到索引5的值(不包括5)print(arr[:5])print("---------------")# 切片,列印arr中從第一個數開始以2位步長到最後一個數的值print(arr[::2])
運作結果如下。
一維ndarray索引和切片
2、二維ndarray的基本索引和切片
import numpy as nparr = np.arange(15).reshape(3, 5)print(arr)print("---------------")# 索引,列印行索引為1的那一行的值print(arr[1])print("---------------")# 索引,列印行索引為1,列索引為1的值print(arr[1][1])print(arr[1, 1])print("---------------")# 切片,列印行索引從開始到行索引為2(不包括2)的幾行值print(arr[:2])print("---------------")# 切片,列印行索引從第一行到行索引為2(不包括2),列索引從2開始(包括2)到最後一列的值print(arr[:2, 2:])
運作結果如下。
二維ndarray索引和切片
3、三維ndarray的基本索引和切片
import numpy as nparr = np.arange(16).reshape(4, 2, 2)print(arr)print("---------------")# 索引print(arr[1][1][1])print("---------------")# 切片print(arr[1:])
運作結果如下。
三維ndarray索引和切片
四維以上的ndarray使用索引和切片的方法以此類推即可。
- 布爾型索引和切片
NumPy中還有一種布爾型的索引和切片,布爾型有True和False兩個值,對ndarray使用布爾型索引和切片會取出布爾值為True的值,需要注意的是用于索引和切片的布爾型數組的長度和待操作的ndarray的操作軸的大小必須一緻。另外,布爾型數組也可與切片,整數(整數序列)一起使用。基本用法如下。
import numpy as nparr = np.arange(12).reshape(3, 4)print(arr)print("---------------")x = np.array([True, False, True])y = np.array([True, True, False, False])print(x)print(y)print("---------------")# 對第一維(這裡是行)操作print(arr[x])print("---------------")# 對第二維(這裡是列)操作print(arr[:, y])print("---------------")print(arr>6)print("---------------")print(arr[arr>6])
對第一維操作時,可省略後面的次元,但對非第一維操作時,其他次元上的值不能忽略,可用“:”表示其他次元上的所有值。除了顯示的設定布爾型數組進行索引和切片,還可以使用條件表達式,上述代碼中我們列印了arr>6的值,可以看到,傳回的是一個與arr形狀一緻的布爾型ndarray,再使用新生成的布爾型ndarray對arr進行索引,得到的将會是一個滿足條件的一維ndarray。運作結果如下所示。
布爾型索引和切片
總結
以上介紹了NumPy中的幾個常用函數以及ndarray的索引和切片,下次我們開始介紹NumPy中的各種資料運算處理。感謝大家的關注,歡迎批評指正,一起交流~