Python乾貨-Numpy的ndarray的合併與分割
# 導入numpy
import numpy as np
ndarray的合併
定義要使用的數據源
a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
print(a, a)
print(b, b)
<class numpy.ndarray>
a [1 1 1]
b [2 2 2]
numpy.vstack()函數
語法:vstack(tup)
,參數是一個元組,它可將元組中指定的數組進行合併
# 將a與b合併
c = np.vstack((a, b))
print(合併結果:
, c)
print(c的形狀:
, c.shape)
合併結果:
[[1 1 1]
[2 2 2]]
c的形狀:
(2, 3)
從結果來看,兩上一維數組合併後的結果是一個地維數組
numpy.hstack()函數
語法:hstack(tup)
,參數是一個元組
與 vstack不同的是,vstack將數組進行縱向合併,而hstack將數組進行橫向合併
vstack 是 vertical stack 的縮寫
hstack 是 horizontal stack 的縮寫
# 將a與b合併
c = np.hstack((a, b))
print(合併結果:
, c)
print(c的形狀:
, c.shape)
合併結果:
[1 1 1 2 2 2]
c的形狀:
(6,)
可以看出,兩個一維數組對象橫向合併後,還是一個一維的序列,不過,元素的個數是被合併數組元素個數之和
將a或b行轉成列
a = a.T
print(a)
[1 1 1]
上面的方式是無法將a進行行轉列的,原因是a是個一維數組,它根本就沒有列,正確的方式是:
c = a.reshape((3, 1))
print(c)
[[1]
[1]
[1]]
重新定義形狀後,現在a是一個3行1列的矩陣,即一個二維數據
思考:a.reshape()是將a所指向的數組的形狀改變了嗎?再來查看a
print(a)
[1 1 1]
實際上,a.reshape()
只是創建了一個a的副本,然後將該副本的內存地址賦給了變數c,而a變數所指向的數組還是原來的對象
newaxis屬性
還有另外一組方式可以改變a的形狀,也是返回一個不置可否;axis表示「軸」的意思
# 在行上增加一個維度(增加一個軸)
c = a[np.newaxis, :]
print(c)
print(c.shape)
print(-*15)
# 在列上增加一個維度
c = a[:, np.newaxis]
print(c)
print(c.shape)
[[1 1 1]]
(1, 3)
---------------
[[1]
[1]
[1]]
(3, 1)
可以看出,返回的新對象的維度都已經發生了變化,在列方向上增加維度以後,將原先的一維數組變成了縱向的二維數組
_a = a[:, np.newaxis]
_b = b[:, np.newaxis]
c = np.hstack((_a, _b))
print(c)
[[1 2]
[1 2]
[1 2]]
也可以將同一個對象進行合併
print(np.hstack((_a, _a, _b, _b)))
[[1 1 2 2]
[1 1 2 2]
[1 1 2 2]]
concatenate()
也可以將數組進行合併,通過axis可以指定合併的方向
# 橫向合併
c = np.concatenate((_a, _a, _b, _b), axis=1)
# 縱向合併
d = np.concatenate((_a,_b), axis=0)
print(c)
print(-*10)
print(d)
[[1 1 2 2]
[1 1 2 2]
[1 1 2 2]]
----------
[[1]
[1]
[1]
[2]
[2]
[2]]
ndarray的分割
定義操作的數據源
# 定義操作的數據源
a = np.arange(12).reshape((3,4))
print(a)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
按列分割
print(a)
print(-*15)
print(np.split(a, 2, axis=1))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
---------------
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
split
第一個參數指要被分割的數組對象,第二個參數指將該對象分成幾份,第三個參數指是從橫向分割還是縱向分割,這裡按列將其分成了兩部分,類似於一個西瓜從上切下,切成了左右兩半!按列分割,指定參數axis=1
按行分割
print(a)
print(-*15)
print(np.split(a, 3, axis=0))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
---------------
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
split
第一個參數指要被分割的數組對象,第二個參數指將該對象分成幾份,第三個參數指是從橫向分割還是縱向分割,這裡按行將其分成了三部分,類似於一個西瓜肚子上橫切兩刀,切成了上中下三部分!按行分割,指定參數axis=0
如果要將三行的數據分成2份,是分報錯的,如下
print(np.split(a, 2, axis=0))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~Anaconda3envstensorflowlibsite-packagesnumpylibshape_base.py in split(ary, indices_or_sections, axis)
534 try:
--> 535 len(indices_or_sections)
536 except TypeError:
TypeError: object of type int has no len()
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-42-7bb000e8eddf> in <module>()
----> 1 print(np.split(a, 2, axis=0))
~Anaconda3envstensorflowlibsite-packagesnumpylibshape_base.py in split(ary, indices_or_sections, axis)
539 if N % sections:
540 raise ValueError(
--> 541 array split does not result in an equal division)
542 res = array_split(ary, indices_or_sections, axis)
543 return res
ValueError: array split does not result in an equal division
如果要對數組進行不對等分割,類似於3行分成2份,則需要用到np.array_split()
print(a)
print(-*15)
print(np.array_split(a, 2, axis=0))
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
---------------
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
在不對等的分割中,並不會出現1.5行這樣的情況,所以會分成2行和1行
vsplit()和hsplit()
# 縱向分割
print(np.vsplit(a, 3))
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
vsplit()中的v是指Vertical的意思,指縱向的,垂直的;按行分割就是縱向分割,因為數據被分成了上下部分,類似於西瓜橫切
# 橫向分割
print(np.hsplit(a, 2))
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
hsplit()中的h是Horizontal的意思,指橫向;按列分割就是橫向的意思,因為將數據分成了左右兩半,就像西瓜縱切
推薦閱讀: