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('合併結果:\n', c)
print('c的形狀:\n', 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('合併結果:\n', c)
print('c的形狀:\n', 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)

    ~\Anaconda3\envs\tensorflow\lib\site-packages\numpy\lib\shape_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))


    ~\Anaconda3\envs\tensorflow\lib\site-packages\numpy\lib\shape_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的意思,指橫向;按列分割就是橫向的意思,因爲將數據分成了左右兩半,就像西瓜縱切

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章