在昨天的文章中介紹到如何在 NumPy 建立各種不同的陣列,以及如何取值與取出 sub-array 。今天來聊聊一些更進階的陣列操作方法!
假設我們有兩個陣列如下:
x = np.array([1, 2, 3]) #[1, 2, 3]
y = np.array([4, 5, 6]) #[4, 5, 6]
我們可以用 np.concatenate()
方法將兩個陣列合併成
np.concatenate([x, y]) #array([1, 2, 3, 4, 5, 6])
不過讓我們今天要合併二維陣列,甚至是更高維度的陣列又會是什麼情況呢?讓我們來看看以下的例子,先用以下兩個式子產生兩個 2x3 的二維陣列
x = np.random.randint(0, 10, (2, 3))
y = np.random.randint(10, 20, (2, 3))
x 與 y 分別為
#x
[[0 6 5]
[3 0 3]]
#y
[[11 13 11]
[15 18 12]]
用 np.concatenate()
合併的結果為
array([[ 0, 6, 5],
[ 3, 0, 3],
[11, 13, 11],
[15, 18, 12]])
我們會發現,陣列是沿著第一層的方向合併的。在 NumPy 當中,
np.concatenate([x, y])
其實就等於
np.concatenate([x, y], axis=0)
如果我們使用
np.concatenate([x, y], axis=1)
結果會變成
array([[ 0, 6, 5, 11, 13, 11],
[ 3, 0, 3, 15, 18, 12]])
長得不太一樣了!
在這個例子中,沿著 axis=0 的方向合併,其實就是
new_array = [x[0],x[1],y[0],y[1]]
而沿著 axis=1 的方向合併,則是
new_array = [[x[0]元素 + y[0]元素],[x[1]元素 + y[1]元素]]
在 NumPy 當中,我們可以讓多個陣列根據我們指定的方向(axis)合併,因此有非常大的操作彈性!
在分割陣列的方法上,NumPy 也提供了很方便的方法。我們先從一維陣列來看
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
假設我們要把上面這個陣列的 10 個元素切成三份,分別儲存在三個不同的變數當中。分割的方法是 3, 2, 5,我們可以用下面這個方法
x1, x2, x3 = np.split(arr, [3, 5])
得到的結果就會是
[1,2,3] #x1
[4,5] #x2
[6,7,8,9,10] #x3
如果我們要分割二維的陣列,則會有兩種切法,一種是 vsplit,顧名思義是 vertical split,也當然另外一種就是 hsplit,也就是 horizontal split
假設我們現在有個 3x3 的二維陣列為
#arr
[[0 1 2]
[3 4 5]
[6 7 8]]
假設今天我們想要從第一層去分割,變成第一層分別有 2 個、1 個元素的兩個陣列
x1, x2 = np.vsplit(arr, [2])
其結果會是
#x1
[[0 1 2]
[3 4 5]]
#x2
[[6 7 8]]
這個切法看起來蠻簡單的,不過 NumPy 提供了另外一個更厲害的分割方式 hsplit
x3, x4 = np.hsplit(arr, [2])
其結果會變成
#x3
[[0 1]
[3 4]
[6 7]]
#x4
[[2]
[5]
[8]]
看起來就像是水平左右切開了!也就是保持分割的陣列第一層 (axis) 的數量還是跟原本的陣列一樣,不過在第二層分割開了
?
查詢文件這裡讓我先岔個題,來提一下之前想提但是沒有機會提到的 IPython
IPython 是一個 python 的互動式 shell,內建許多 "magic function" 來幫助程式開發者完成任務,像是用 %timeit 來測量程式碼執行時間,用 %debug 來進行 debug 等等。你可以在 Jupyter 中打上 %magic
並執行,就可以看到 magic function 的相關介紹
不過我認為最常用到的是 ?
這個方法。舉例來說,假如我們不知道 np.hsplit 該怎麼使用,我們可以很簡單的在 Jupyter 當中打上 np.hsplit
然後加上一個 ?
,執行之後,就會看到下面跑出說明文件。
這個方法不僅僅可以用在檢查不同的方法,也可以檢查你目前在使用的變數的細節,非常方便喔!
希望今天的合併與分割陣列內容不會讓大家看得暈頭轉向,明天我們繼續看看 NumPy 的其他功能!