1. 程式人生 > >關於Numpy中transpose()和stack()函式的解析!(Numpy.transpose()和Numpy.stack())

關於Numpy中transpose()和stack()函式的解析!(Numpy.transpose()和Numpy.stack())

最近在看斯坦福大學的cs231n機器學習課程,第一節的assignment1裡的KNN線性分類器中用到了這兩個函式,由於我是新手,就看不懂這兩個函式坐了什麼,其實結合那個例程,這個函式當時會覺得好像明白了它的意思,但是後來在CSDN上看了一個講stack()函式的部落格,徹底把我搞懵了,研究了一天,結果發現這兩個函式(Numpy.transpose()和Numpy.stack())是有很強的相似性的。下面開始分析,因為本人也是研究生一枚,剛入機器學習不久,錯誤之處,還望大神不吝指正,郵箱評論均可(郵箱:[email protected])。

首先,網上關於Numpy.stack()的具體理解還是很少的,其中有一篇博主寫的很詳細,但是長篇大論都在講自己怎麼理解,我看了一半我真的不知道這個部落格在講什麼,什麼套箱子,什麼的。好吧可能是我太菜了,也有很多說看懂的,能看懂的可以嘗試去看一看。但是,我覺得這個函式的設計絕不是那樣的,官方文件幾句話就解釋完了(雖然並沒有理解),所以說它應該沒有那麼複雜。連結在這,可自行檢視:

https://blog.csdn.net/csdn15698845876/article/details/73380803

我為什麼要把Numpy.stack()和Numpy.transpose()放在一起來講呢,他們真的是有共同點的。我不想在這裡做重複的事情,所以,有前輩貢獻的,我直接甩連結,大家點進去看,有補充的我會在後面補充。

首先是Numpy.transpose()函式,

好吧,為了照顧英文不好的,我再以我的方式解釋一下,(我的英文也不好,有錯誤的地方,歡迎指正)

大致的意思就是,以x.transpose()方式引用,接收一個引數(*axes,函式對一維陣列沒有作用,函式通過引數axes來變換傳入陣列的形狀(shape)

axes引數一共有三種傳入方式

①:不傳入,即預設

假如原陣列的shape是(0,1,2,3,4,...,n-1),變換以後是(n-1,...2,1,0)

②:傳入元組

傳入的元組必須和當前元組的維度個數相同,也就是現在是n維的陣列,那麼axes引數也必須是n維,而且元組的數必須是0到n-1的每一個數字組成的,代表新的陣列的維度

例如一個三維的陣列,shape是(2,3,4),axes陣列必須是0,1,2這三個數,你可以是(0,1,2),這個表示不變化,也可以是(1,0,2)這個變換後的shape是(3,2,4),也可以是(2,1,0),這個變換後的shape是(4,2,3),也可以是(2,0,1),這個變換後的shape是(4,3,2)。

應該看明白了吧,例子自己舉吧,列個數組就明白了,就是指定維度變換方式,所以這個很好理解。

還有個帖子我覺得寫得不錯,很詳細,我很懶,懶得畫圖解釋了,你們可以看看這個:

關於這個函式,寫得好的帖子應該很多,不滿意我的解釋或者我推薦的也不滿意,可以自行查詢。

那麼可能有人要問,變換後陣列的數是怎麼排布的呢?先不著急,先看Numpy.stack()函式

Numpy.stack()函式,

這個函式,我真的沒找到幾個好的解釋,官方文件算一個,在這:

還有就是上面提到的那個,說了很多雲裡霧裡的:

真正讓我有啟發的是這個:

具體變換過程其實是和transpose()很相似的,只是transpose()需要一個元組來設計變換後的shape,而stack()只要一個axis來指定變換後的shape,具體變換方法看上個連線就好。

那麼,最令人費解的是什麼,是變換後的數,這也是兩個函式的共同點,這兩個函式,對傳入的數不管是列表也好,元組也好,都會先使用numpy.array()變換,變換後的陣列會是作為一個原型,以後所有的Numpy.transpose()和Numpy.stack()的作用都是在這個原型的基礎上旋轉得來的,舉例來說,當輸入的原型是三維的,你可以想象成一個立方體,所有你做的變換最終得到的陣列的數字排列,只是這個立方體從不同的角度看得到的多維陣列,各個數字之間的相對位置是不變的。這個只能想,沒法畫。可以寫程式碼驗證。

#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
# @Time    : 2018/9/13 17:04
# @Author  : Allen
# @File    : test.py
# @Software: PyCharm


import numpy as np

a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
b = [[21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35], [36, 37, 38, 39, 40]]
c = [[41, 42, 43, 44, 45], [46, 47, 48, 49, 50], [51, 52, 53, 54, 55], [56, 57, 58, 59, 60]]


x = np.array((a, b, c))
print(x)
print(x.shape)

y = np.stack(x)
print(y)
print(y.shape)

z = np.stack(x, axis=0)
print(z)
print(z.shape)

w = np.stack(x, axis=1)
print(w)
print(w.shape)

g = np.stack(x, axis=2)
print(g)
print(g.shape)

h = np.stack(x, axis=2)
print(h)
print(h.shape)

k = np.stack(x, axis=-1)
print(k)
print(k.shape)

x = np.array((a, b, c))
print(x)
print(x.shape)

p = x.transpose((0, 1, 2))
print(p)
print(p.shape)

q = x.transpose((1, 0, 2))
print(q)
print(q.shape)

i = x.transpose((1, 2, 0))
print(i)
print(i.shape)

i = x.transpose((2, 1, 0))
print(i)
print(i.shape)

結果太長就不貼上了,可以自行執行。

寫程式碼的時候發現在google其實是能找到stack的詳解的,沒那麼少。而且好像講述了立方體的意思,都寫到這裡了不能白寫,既然寫了,就放出來,希望可以幫到某些人。如果有錯誤的地方,歡迎指正([email protected])。或者你看的一頭霧水,那就選擇其他途徑吧!到此為止。歡迎閱讀!