# 導入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的意思,指橫向;按列分割就是橫向的意思,因為將數據分成了左右兩半,就像西瓜縱切


推薦閱讀:
相关文章