TShopping

 找回密碼
 註冊
搜索
查看: 60|回復: 0

[教學] Numpy中stack(),hstack(),vstack()函式用法介紹及例項

[複製鏈接]
發表於 2021-1-7 13:59:50 | 顯示全部樓層 |閱讀模式
 
Push to Facebook Push to Plurk  
1.stack()函式
函式原型為:stack(arrays,axis=0),arrays可以傳陣列和列表。axis的含義我下面會講解,我們先來看個例子,然後我會分析輸出結果。
  1. import numpy as np
  2. a=[[1,2,3],
  3. [4,5,6]]
  4. print("列表a如下:")
  5. print(a)
  6. print("增加一維,新維度的下標為0")
  7. c=np.stack(a,axis=0)
  8. print(c)
  9. print("增加一維,新維度的下標為1")
  10. c=np.stack(a,axis=1)
  11. print(c)
  12. 輸出:
  13. 列表a如下:
  14. [[1, 2, 3], [4, 5, 6]]
  15. 增加一維,新維度下標為0
  16. [[1 2 3]
  17. [4 5 6]]
  18. 增加一維,新維度下標為1
  19. [[1 4]
  20. [2 5]
  21. [3 6]]
複製代碼

首先這裡arrays我傳的是一個列表,現在我開始講解這個stack()函式的意思,它就是對arrays裡面的每個元素(可能是個列表,元組,或者是個numpy的陣列)變成numpy的陣列後,再對每個元素增加一維(至於維度加在哪裡,是靠axis控制的),然後再把這些元素串起來(至於怎麼串,我下面會說)。
arrays裡面的每個元素必須形狀是一樣的,例如本例中列表a中的兩個元素[1,2,3]和[4,5,6]的形狀是一樣的,如果把[4,5,6]換成[4,5] ,那麼程式會報錯!而axis代表的是在哪個維度上加一維,例如axis=0(它是預設的)代表的就是增加的這一維的下標為0,axis等於多少不是隨便亂寫的,如果引數arrays裡面的每個元素是個1維的,那麼呼叫stack()函式增加一維後會變成2維的,所以axis只能等於0和1(維度的下標是從0開始的),而引數axis=0和axis=1得到的結果是不一樣的。
例如上面的程式碼中a列表中的第一個元素為[1,2,3],那麼當axis=0的時候,就是在它的中括號外面再加一箇中括號,變成[ [1,2,3] ](其實1,2,3之間是沒有逗號的,因為stack()函式會先把引數arrays中的每個元素變成numpy的陣列,陣列之間是沒有逗號的,看看上面的程式碼輸出就知道了,這裡大家明白就行,我為了方便講解,下面還會加上逗號),這樣最外面那層中括號才代表維度下標為0的那維;當axis=1的時候,就是在裡面加個中括號,變成了[ [1],[2],[3] ],這樣裡面加的那層中括號才代表維度下標為1的那維。同理當axis=0的時候[4,5,6]變成[ [ 4,5,6] ],當axis=1的時候,變成[ [4],[5],[6] ]。下面我們講如何把增加一維度後的每個元素串起來。
怎麼把上面那兩個元素增加維度後的結果串起來呢,其實很簡單。現在我們已經知道了增加維度無非是增加中括號的意思,至於在哪裡加中括號,取決於axis等於幾。我們把增加的中括號想像成一個個的箱子。還拿上面的程式碼來說,當axis=0的時候,我們把套在[1,2,3]外面的中括號(就是[ [1,2,3] ]最外層的那個中括號)看做是箱子A,這個箱子A也會套在[4,5,6]的外面,所以我們就先把[1,2,3]和[4,5,6]放在一起,變成[1,2,3],[4,5,6],然後再一起套上箱子A,變成[ [1,2,3],[4,5,6] ]這就是當axis=0的時候程式的輸出結果。
現在再來看當axis=1的時候,對於[1,2,3],我們把套在1外面的箱子(就是上面講的[ [1],[2],[3] ]中1外面的那層中括號)看做A,套在2外面的看做B,套在3外面的看做C,同理,箱子A也會套在4的外面,箱子B也會套在5的外面,箱子C也會套在6的外面。那麼我們就把1和4放一起,2和5放一起,3和6放一起,變成[ 1,4 ,2,5 ,3,6 ]然後把箱子A,B,C分別套在1,4 , 2,5 , 3,6的外面,變成[ [1,4] , [2,5] , [3,6] ]這就是程式中axis=1的時候程式的輸出結果。
大家發現了沒有,串起來的時候其實就是把arrays中每個元素在相同的位置套箱子的一些小塊(這裡叫小塊這個名詞可能不洽當,但是大家明白就行)放在一起後,再套箱子,就是外面套個中括號,這就是堆疊。
再看下面的程式碼的輸出,測試下你理解的沒有。
  1. import numpy as np
  2. a=[[1,2,3,4],
  3. [5,6,7,8],
  4. [9,10,11,12]]
  5. print("列表a如下:")
  6. print(a)
  7. print("增加一維,新維度的下標為0")
  8. c=np.stack(a,axis=0)
  9. print(c)
  10. print("增加一維,新維度的下標為1")
  11. c=np.stack(a,axis=1)
  12. print(c)
  13. 輸出:
  14. 列表a如下:
  15. [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
  16. 增加一維,新維度的下標為0
  17. [[ 1 2 3 4]
  18. [ 5 6 7 8]
  19. [ 9 10 11 12]]
  20. 增加一維,新維度的下標為1
  21. [[ 1 5 9]
  22. [ 2 6 10]
  23. [ 3 7 11]
  24. [ 4 8 12]]
複製代碼

不知道和你想象的輸出一樣不一樣,還有另一種情況,先看下面的程式碼。
  1. import numpy as np
  2. a=[1,2,3,4]
  3. b=[5,6,7,8]
  4. c=[9,10,11,12]
  5. print("a=",a)
  6. print("b=",b)
  7. print("c=",c)
  8. print("增加一維,新維度的下標為0")
  9. d=np.stack((a,b,c),axis=0)
  10. print(d)
  11. print("增加一維,新維度的下標為1")
  12. d=np.stack((a,b,c),axis=1)
  13. print(d)
  14. 輸出:
  15. ('a=', [1, 2, 3, 4])
  16. ('b=', [5, 6, 7, 8])
  17. ('c=', [9, 10, 11, 12])
  18. 增加一維,新維度的下標為0
  19. [[ 1 2 3 4]
  20. [ 5 6 7 8]
  21. [ 9 10 11 12]]
  22. 增加一維,新維度的下標為1
  23. [[ 1 5 9]
  24. [ 2 6 10]
  25. [ 3 7 11]
  26. [ 4 8 12]]
複製代碼

你會發現輸出結果和上面的程式碼一樣,其實它倆就是一樣的。只不過當你對arrays傳參的時候,如果你傳的引數是類似於(a,b,c)這種,它會把(a,b,c)當做一個元組來看,a,b,c都是元組的每個元素。然後分別對每個元素處理,上面我已經說了,arrays傳的引數可以是列表,元組,或者numpy陣列。所以傳(a,b,c)和傳[a,b,c]或者當x=[a,b,c]的時候傳x,效果都是一樣的。
上面的程式碼處理的arrays元素都是一維變二維的情況,下面我們看看二維變三維是什麼樣的。
  1. import numpy as np
  2. a=[[1,2,3],
  3. [4,5,6]]
  4. b=[[1,2,3],
  5. [4,5,6]]
  6. c=[[1,2,3],
  7. [4,5,6]]
  8. print("a=",a)
  9. print("b=",b)
  10. print("c=",c)
  11. print("增加一維,新維度的下標為0")
  12. d=np.stack((a,b,c),axis=0)
  13. print(d)
  14. print("增加一維,新維度的下標為1")
  15. d=np.stack((a,b,c),axis=1)
  16. print(d)
  17. print("增加一維,新維度的下標為2")
  18. d=np.stack((a,b,c),axis=2)
  19. print(d)
  20. 輸出:
  21. ('a=', [[1, 2, 3], [4, 5, 6]])
  22. ('b=', [[1, 2, 3], [4, 5, 6]])
  23. ('c=', [[1, 2, 3], [4, 5, 6]])
  24. 增加一維,新維度的下標為0
  25. [[[1 2 3]
  26. [4 5 6]]
  27. [[1 2 3]
  28. [4 5 6]]
  29. [[1 2 3]
  30. [4 5 6]]]
  31. 增加一維,新維度的下標為1
  32. [[[1 2 3]
  33. [1 2 3]
  34. [1 2 3]]
  35. [[4 5 6]
  36. [4 5 6]
  37. [4 5 6]]]
  38. 增加一維,新維度的下標為2
  39. [[[1 1 1]
  40. [2 2 2]
  41. [3 3 3]]
  42. [[4 4 4]
  43. [5 5 5]
  44. [6 6 6]]]
複製代碼

當axis=0的時候,列表a,b,c最外面都需要套箱子(就是加中括號),那麼我把你們先放一起,變成下面這樣
  1. [[1,2,3],[4,5,6]],
  2. [[1,2,3],[4,5,6]],
  3. [[1,2,3],[4,5,6]]
複製代碼

然後在最外面套箱子,變成
  1. [
  2. [[1,2,3],[4,5,6]],
  3. [[1,2,3],[4,5,6]],
  4. [[1,2,3],[4,5,6]]
  5. ]
複製代碼

當axis=1的時候,列表a,b,c中的[1,2,3]需要套同樣的箱子,列表a,b,c中的[4,5,6]需要套同樣的箱子,好,我先把你們放一塊變成下面這樣
  1. [
  2. [1,2,3],[1,2,3],[1,2,3]
  3. ,
  4. [4,5,6],[4,5,6],[4,5,6]
  5. ]
複製代碼

然後開始分別在 [1,2,3],[1,2,3],[1,2,3]的外面和[4,5,6],[4,5,6],[4,5,6]的外面套箱子,變成下面這樣
  1. [
  2. [[1,2,3],[1,2,3],[1,2,3]]
  3. ,
  4. [[4,5,6],[4,5,6],[4,5,6]]
  5. ]
複製代碼

當axis=2的時候,列表a,b,c中的1,2,3,4,5,6都需要套箱子,我把你們先放一起變成:
  1. [
  2. [1,1,1 , 2,2,2 , 3,3,3],
  3. [4,4,4 , 5,5,5 , 6,6,6]
  4. ]
複製代碼

然後在1,1,1 ………6,6,6的外面分別套箱子變成:
  1. [
  2. [[1,1,1] , [2,2,2] , [3,3,3]],
  3. [[4,4,4] , [5,5,5] , [6,6,6]]
  4. ]
複製代碼

關於stack()函式就講這麼多,這也是我全部理解的部分。

2. hstack()函式
函式原型:hstack(tup) ,引數tup可以是元組,列表,或者numpy陣列,返回結果為numpy的陣列。看下面的程式碼體會它的含義
  1. import numpy as np
  2. a=[1,2,3]
  3. b=[4,5,6]
  4. print(np.hstack((a,b)))
  5. 輸出:[1 2 3 4 5 6 ]
複製代碼

  1. import numpy as np
  2. a=[[1],[2],[3]]
  3. b=[[1],[2],[3]]
  4. c=[[1],[2],[3]]
  5. d=[[1],[2],[3]]
  6. print(np.hstack((a,b,c,d)))
  7. 輸出:
  8. [[1 1 1 1]
  9. [2 2 2 2]
  10. [3 3 3 3]]
複製代碼

它其實就是水平(按列順序)把陣列給堆疊起來,vstack()函式正好和它相反。

3. vstack()函式
函式原型:vstack(tup) ,引數tup可以是元組,列表,或者numpy陣列,返回結果為numpy的陣列。看下面的程式碼體會它的含義
  1. import numpy as np
  2. a=[1,2,3]
  3. b=[4,5,6]
  4. print(np.vstack((a,b)))
  5. 輸出:
  6. [[1 2 3]
  7. [4 5 6]]
複製代碼
  1. import numpy as np
  2. a=[[1],[2],[3]]
  3. b=[[1],[2],[3]]
  4. c=[[1],[2],[3]]
  5. d=[[1],[2],[3]]
  6. print(np.vstack((a,b,c,d)))
  7. 輸出:
  8. [[1]
  9. [2]
  10. [3]
  11. [1]
  12. [2]
  13. [3]
  14. [1]
  15. [2]
  16. [3]
  17. [1]
  18. [2]
  19. [3]]
複製代碼

它是垂直(按照行順序)的把陣列給堆疊起來。


 

臉書網友討論
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2021-1-22 05:11 , Processed in 0.059358 second(s), 20 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表