20 數組高階操作函數(下)
Numpy 提供了一系列針對數組操作的高階函數,除了比較常見的合并,還有分割、追加、插入等操作。
1. 數組的分割
1.1 numpy.split 函數
numpy.split 函數將數組的副本沿指定軸劃分為子數組。該函數的原型如下:
numpy.split(arr, indices_or_sections, axis=0)
參數說明如下:
參數 | 說明 |
---|---|
arr | 待拆分的輸入數組 |
indices_or_sections | 整數,表示要從輸入數組創建的相等大小的子數組的數量。如果是1-D數組,則條目指示要創建新子數組的點。 |
axis | 連接數組的軸的方向,默認值為0 |
案例
對于一維數組的情形,非常簡單。創建1維數組:
arr_1 = np.array([12, 23, 34, 45, 56, 67, 78, 89, 100, 110, 120, 130])
利用numpy.split函數將arr_1等分為3塊:
np.split(arr_1, 3)
out:
[array([12, 23, 34, 45]), array([56, 67, 78, 89]), array([100, 110, 120, 130])]
當 indices_or_sections 參數為常數時,numpy.split 函數是講數組進行等分。對于無法等分的情況,會報 ValueError 的錯誤。
當 indices_or_sections 參數為整數列表時,表示按照以整數為位置索引進行分割:
np.split(arr_1, [3, 6])
out:
[array([12, 23, 34]), array([45, 56, 67]), array([ 78, 89, 100, 110, 120, 130])]
案例
對于多維數組的情形,將內層的數組視為整體,僅考慮最外層的大小進行切割:
arr_2 = arr_1.reshape(6,2)
arr_2
out:
array([[ 12, 23],
[ 34, 45],
[ 56, 67],
[ 78, 89],
[100, 110],
[120, 130]])
對 arr_2 進行切割:
np.split(arr_2, 3)
out:
[array([[12, 23],[34, 45]]),
array([[56, 67],[78, 89]]),
array([[100, 110],[120, 130]])]
案例
可以通過指定 axis 來限制實際產生分割的維度。例如,對 arr_2 控制分割點在水平位置(axis=1):
np.split(arr_2, 2, axis=1)
out:
[array([[ 12],
[ 34],
[ 56],
[ 78],
[100],
[120]]), array([[ 23],
[ 45],
[ 67],
[ 89],
[110],
[130]])]
需要注意比較 axis=1 和默認(axis=0)參數時的區別。
1.2 numpy.hsplit 函數
numpy.hsplit 是 split() 函數的一個特例,其中 axis 為 1 表示水平分割,與輸入數組的維度無關。
案例
對上述指定 axis=1(水平分割)時的分割效果,可以用 numpy.hsplit 改寫如下:
np.hsplit(arr_2, 2)
out:
[array([[ 12],
[ 34],
[ 56],
[ 78],
[100],
[120]]), array([[ 23],
[ 45],
[ 67],
[ 89],
[110],
[130]])]
1.3 numpy.vsplit 函數
numpy.vsplit 是 split() 函數的一個特例,其中 axis 為 1 表示垂直分割,與輸入數組的維度無關。
案例
對于上述指定 axis=0(默認參數)時的分割效果,可以用 numpy.vsplit 改寫如下:
np.vsplit(arr_2, 3)
out:
[array([[12, 23],[34, 45]]),
array([[56, 67],[78, 89]]),
array([[100, 110],[120, 130]])]
2. 數組追加
2.1 numpy.append 函數
numpy.append 函數可以在輸入數組末尾,追加一個尺寸匹配的數組,與列表中 append 的操作類似。但是輸入數組的尺寸必須匹配,否則將生成 ValueError。該函數的原型如下:
numpy.append(arr, values, axis)
參數說明如下:
參數 | 說明 |
---|---|
arr | 輸入數組 |
values | 待追加的數組,values在不包括附加軸的情況下,其形狀需與arr保持一致 |
axis | 附加操作的軸。如果沒有給出,則兩個參數會先折疊為一維 |
案例
以二維數組為例,對 arr_2 的 axis=0 方向追加數組:
np.append(arr_2, [[1, 2]], axis=0)
out:
array([[ 12, 23],
[ 34, 45],
[ 56, 67],
[ 78, 89],
[100, 110],
[120, 130],
[ 1, 2]])
案例
以二維數組為例,對 arr_2 的 axis=1 方向追加數組:
np.append(arr_2, [[1], [2], [3], [4], [5], [6]], axis=1)
out:
array([[ 12, 23, 1],
[ 34, 45, 2],
[ 56, 67, 3],
[ 78, 89, 4],
[100, 110, 5],
[120, 130, 6]])
案例
當不指定 axis 時,在追加動作產生前,會先把輸入數組展平:
np.append(arr_2, [[1], [2], [3], [4], [5], [6]])
out:
array([ 12, 23, 34, 45, 56, 67, 78, 89, 100, 110, 120, 130, 1, 2, 3, 4, 5, 6])
當不指定axis時,append結果為一維數組。
3. 數組的插入
3.1 numpy.insert 函數
numpy.insert 函數沿給定軸和給定索引之前在輸入數組中插入值。該函數的原型如下:
numpy.insert(arr, obj, values, axis)
參數說明如下:
參數 | 說明 |
---|---|
arr | 輸入數組 |
obj | 待插入位置的索引 |
values | 待插入的值數組 |
axis | 要插入的軸。如果沒有指定,則輸入數組會先折疊為一維 |
案例
對于不指定 axis 的情形:
np.insert(arr_2, 2, [123, 456])
out:
array([ 12, 23, 123, 456, 34, 45, 56, 67, 78, 89, 100, 110, 120, 130])
可以發現,對于 insert 函數,新插入的元素從指定的位置(索引為2)開始,其他元素往后平移。
案例
指定在 axis=0 的軸上插入新元素:
np.insert(arr_2, 2, [123, 456], axis=0)
out:
array([[ 12, 23],
[ 34, 45],
[123, 456],
[ 56, 67],
[ 78, 89],
[100, 110],
[120, 130]])
案例
當指定插入的元素跟輸入數組形狀不一致時,可以通過廣播規則進行傳播補齊。當不滿足廣播規則,則會報 ValueError 的錯誤。
np.insert(arr_2, 2, [123], axis=0)
out:
array([[ 12, 23],
[ 34, 45],
[123, 123],
[ 56, 67],
[ 78, 89],
[100, 110],
[120, 130]])
案例
指定在 axis=1 的軸上插入新元素:
np.insert(arr_2, 2, [1, 2, 3, 4, 5, 6], axis=1)
out:
array([[ 12, 23, 1],
[ 34, 45, 2],
[ 56, 67, 3],
[ 78, 89, 4],
[100, 110, 5],
[120, 130, 6]])
4. 小結
本節講述了數組分割與追加的常用方法,其中append函數與insert函數在不指定操作軸的時候,函數會首先對輸入數組進行展開操作。而hsplit和vsplit則是已經默認了計算方向,使用過程中注意區分。