numpy的concatenate()、hstack()、vstack()、stack()函數分析

numpy中幾個常用的相似函數concatenate()、hstack()、vstack()、stack()用法相似,不容易區分。現在從形狀的角度,對這4個函數進行總結。

在總結之前,首先介紹一下維度。例如一個3維數組,形狀爲(2, 3, 4)的數組

a = np.arange(24).reshape((2, 3, 4))
print(a)

[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

另外python中(3,)表示一維數組,(3,1)才表示二維數組

1、np.concatenate()函數

用於數組、數列的連接。對一維數組使用時候。

a = [1, 2, 3]  # shape = (3, )
b = [4, 5]     # shape = (2, )

c = np.concatenate((a, b), axis = 0) 
print ('np.concatenate((a, b), axis = 0)的形狀', c.shape)

Output:

np.concatenate((a, b), axis = 0)的形狀 (5,)
  • 由該結果可以看出,對一維函數使用,使兩個數組的形狀在唯一的維度上進行了相加2+3=52+3=5

對於多維數組使用:

a = np.arange(24).reshape((2, 3, 4))          # shape = (2, 3, 4)
b = np.arange(24, 48).reshape((2, 3, 4))      # shape = (2, 3, 4)

c = np.concatenate((a, b), axis = 0)
d = np.concatenate((a, b), axis = 1)
e = np.concatenate((a, b), axis = 2)

print("np.concatenate((a, b), axis = 0)後,結果的形狀爲" , c.shape)
print("np.concatenate((a, b), axis = 1)後,結果的形狀爲" , d.shape)
print("np.concatenate((a, b), axis = 2)後,結果的形狀爲" , e.shape)

Output:

np.concatenate((a, b), axis = 0)後,結果的形狀爲 (4, 3, 4)
np.concatenate((a, b), axis = 1)後,結果的形狀爲 (2, 6, 4)
np.concatenate((a, b), axis = 2)後,結果的形狀爲 (2, 3, 8)

由結果可以看出:

  • 當axis=0時,是將a和b的形狀,在第1個維度進行相加,第2, 3個維度不變,2+2=42+2=4
  • 當axis=1時,是將a和b的形狀,在第2個維度進行相加,第1, 3個維度不變,3+3=63+3=6
  • 當axis=2時,是將a和b的形狀,在第3個維度進行相加,第1, 2個維度不變4+4=84+4=8

重點說一下,數組在連接的維度上的形狀可以不同,但是其他維度必須相同。例如:兩個形狀如(2, 3, 4)和(6, 3, 4)的數組,第1維不同,但是其餘維度相同,可以在第1維進行連接,連接後的形狀爲(8,3,4),測試如下:

## 將a和b在第一個維度進行連接
a = np.arange(24).reshape((2, 3, 4))          # shape = (2, 3, 4)
b = np.arange(24, 96).reshape((6, 3, 4))      # shape = (6, 3, 4)
c = np.concatenate((a, b), axis = 0) 
print ('np.concatenate((a, b), axis = 0)的形狀', c.shape)

Output:

np.concatenate((a, b), axis = 0)的形狀 (8, 3, 4)

同理axis =1時,對下面的a和b在第2個維度進行連接:

a = np.arange(24).reshape((3, 2, 4))          # shape = (3, 2, 4)
b = np.arange(24, 96).reshape((3, 6, 4))      # shape = (3, 6, 4)
c = np.concatenate((a, b), axis = 1) 
print ('np.concatenate((a, b), axis = 1)的形狀', c.shape)

Output:

np.concatenate((a, b), axis = 1)的形狀 (3, 8, 4)

同理axis =2時,對下面的a和b在第3個維度進行連接:

a = np.arange(24).reshape((3, 4, 2))          # shape = (3, 4, 2)
b = np.arange(24, 96).reshape((3, 4, 6))      # shape = (3, 4, 6)
c = np.concatenate((a, b), axis = 2) 
print ('np.concatenate((a, b), axis = 2)的形狀', c.shape)

Output:

np.concatenate((a, b), axis = 2)的形狀 (3, 4, 8)

綜上,concatenate的結果,維度不增加,只在axis對應的維度上進行相加

2、np.vstack()

np.vstack()的作用和concatenate()在axis=0時相似,將數組在第2維度進行連接

a = np.arange(24).reshape((2, 3, 2, 2))          # shape = (2, 3, 2, 2)
b = np.arange(24, 48).reshape((2, 3, 2, 2))      # shape = (2, 3, 2, 2)
c = np.vstack((a, b))
print ('np.vstack((a, b))的形狀爲', c.shape)

Output:

np.vstack((a, b))的形狀爲 (4, 3, 2, 2)

因爲vstack是將數組在第1個維度進行連接,所以第1個維度值可以不同,例如:

a = np.arange(6).reshape(2, 3)   # shape = (2, 3)
b = np.arange(9).reshape(3, 3)   # shape = (3, 3)

c = np.vstack((a, b))
print ('np.vstack((a, b))的形狀爲', c.shape)

Output:

np.vstack((a, b))的形狀爲 (5, 3)

3、np.hstack()

np.hstack()的作用和concatenate()在axis=1時相似,將數組在第2維度進行連接

a = np.arange(24).reshape((2, 3, 2, 2))          # shape = (2, 3, 2, 2)
b = np.arange(24, 48).reshape((2, 3, 2, 2))      # shape = (2, 3, 2, 2)
c = np.hstack((a, b))
print ('np.hstack((a, b))的形狀爲', c.shape)

Output:

np.hstack((a, b))的形狀爲 (2, 6, 2, 2)

因爲hstack是將數組在第s個維度進行連接,所以第2個維度值可以不同,例如:

a = np.arange(6).reshape(2, 3)   # shape = (2, 3)
b = [[1], [2]]                   # shape = (2, 1)

c = np.hstack((a, b))
print ('np.vstack((a, b))的形狀爲', c.shape)

Output:

np.vstack((a, b))的形狀爲 (2, 4)

由此可以看出,concatenate()、hstack()、vstack()3個函數對於數組的維度沒有改變,運算中的a,b是3維數組,運算後仍然是3維數組。這與下面的np.stack()不同

4、np.stack()

np.stack()有堆疊的意思,即將兩個元素堆疊在一起,然後在外面打包,打包過程要求1對1,所以傳入的元素要求shape完全一樣,不然會報錯。

a = np.arange(27).reshape((3,3,3))    # shape = (3,3,3)
b = a+1                               # shape = (3,3,3)

c = np.stack((a, b), axis = 0)        # (2, 3, 3, 3)
d = np.stack((a, b), axis = 1)        # (3, 2, 3, 3)
e = np.stack((a, b), axis = 2)        # (3, 3, 2, 3)
f = np.stack((a, b), axis = 3)        # (3, 3, 3, 2)

print ('axis = 0時的形狀爲', c.shape)
print ('axis = 1時的形狀爲', d.shape)
print ('axis = 2時的形狀爲', e.shape)
print ('axis = 3時的形狀爲', f.shape)

Output:

axis = 0時的形狀爲 (2, 3, 3, 3)
axis = 1時的形狀爲 (3, 2, 3, 3)
axis = 2時的形狀爲 (3, 3, 2, 3)
axis = 3時的形狀爲 (3, 3, 3, 2)

由此可以看出,stack之後,維度由3維變爲了4維,增加的維度由axis指定。

本文只是在維度的角度對numpy的concatenate()、hstack()、vstack()、stack()函數進行了分析,

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