NumPy 1.14 教學 – #09 ix_( )函數、線性代數(Linear Algebra)、重複(Repeat)、堆疊(Stack)
NumPy提供了一個很有趣的函數 ix_ ,一剛開始還有點看不太懂官方文件到底是想表示什麼?
仔細閱讀其他的範例之後發現原來 ix_ 函數的用途應該算是很多樣的。
此外還會介紹np.repeat、np.tile、np.hstack、np.vstack等用法。本文#09應該算是 NumPy教學系列文的最後一篇。
不過,未來若有碰到什麼奇妙的用法也還是會一併補充上來。 😀練習範例同步放置於GitHub:Learn NumPy – GitHub
ix_ function
首先來觀察 ix 函數的運作模式:
可以輸入多個陣列,本範例以輸入兩個一維陣列為例。
ix_ 函數會以第一個作為輸入參數的陣列轉置成 column vector 回傳。
column vector 就是只有一個column的向量(如下所示)。
$\begin{bmatrix}
1\\
3
\end{bmatrix}$
第二個陣列就會被作以 row vector 的形式輸出。
row vector 就是只有一個row的向量(如下所示)。
$\begin{bmatrix}
2 & 4\end{bmatrix}$
如果分別將 ix_( ) 的回傳值分別取出,就可以看出上述的差異。(請參考:下列程式範例第15行、輸出結果第14~18行)
但是如果直接使用一個變數來接收 ix_( ) 的回傳值,會收到一個tuple,這個tuple則是以第一、第二個輸入參數所轉換成的陣列依序組合而成的。(請參考:下列程式範例第8行、輸出結果第9~11行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
martix_a = np.arange(0, 25).reshape(5, 5) print('matrix_a=>\n', martix_a) # ix_() will return a tuple what is composed by array [1,3] and array [2,4]. # ix_() 會回傳一個由[1,3]和[2,4]兩個輸入值而組成的tuple. print() print('np.ix_([1,3],[2,4]))') print('ix_()=>\n{0}'.format(np.ix_([1,3],[2,4]))) # We can seperate the return value of ix_() as two different array. # 我們可以分別將ix_()的回傳值以兩個不同的陣列取出. print() print('Seperate the return value of ix_(): rows, cols = np.ix_([1,3],[2,4])') rows, cols = np.ix_([1,3],[2,4]) print('rows=>\n{0}\ncols=>\n{1}'.format(rows, cols)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
matrix_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 24]] np.ix_([1,3],[2,4])) ix_()=> (array([[1], [3]]), array([[2, 4]])) Seperate the return value of ix_(): rows, cols = np.ix_([1,3],[2,4]) rows=> [[1] [3]] cols=> [[2 4]] |
ix_ 函數把輸入值轉換成這樣,可以用在哪些地方呢?
輸入參數可以是欲選取矩陣中特定資料的索引值,利用 ix_ 對目標矩陣選取需要的資料:
我想要選取上述 matrix_a 矩陣中的索引(1,2)、(1,4)、(3,2)、(3,4)四筆資料,
因此,對應至矩陣的row以及column的索引值可以分別處理成兩個向量:$\begin{bmatrix} 1&3 \end{bmatrix}$ 以及 $\begin{bmatrix} 2&4 \end{bmatrix}$
最後,就可以直接用 ix_ 的回傳值來選取資料!(請參考:下列程式範例第16行、輸出結果第3~5行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# The return value of ix_() can divide into two part: # The first part will is composed by the first input array, # and the first part will become a column vector. # The second part is composed by the second input array, # and it will become a row vector. # Therefor, we can use the return value of ix_() as an index set # to get values from a 2-dimension matrix directly. # ix_()的回傳值分為兩個部分: # 第一部分由第一個輸入陣列組成, 它會變成一個column vector. # 第二部分由第二個輸入陣列組成, 它會變成一個row vector. # 因此, 我們可以利用ix_()的回傳值形成一組索引集, 直接從一個二維陣列中取值. print() print('Get values by ix_():') print('a_ix = martix_a[ np.ix_([1,3],[2,4]) ]') a_ix = martix_a[np.ix_([1,3],[2,4])] print('a_ix=>\n{0}'.format(a_ix)) |
1 2 3 4 5 |
Get values by ix_(): a_ix = martix_a[ np.ix_([1,3],[2,4]) ] a_ix=> [[ 7 9] [17 19]] |
線性代數常用方法
這邊介紹一些較簡單的線性代數方法:矩陣相乘(matrix product)、矩陣內元素相乘(element-by-element multiplication)、轉置(transpose)、單位矩陣(identify matrix)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
##Linear Algebra x1 = np.array([[1, 2], [3, 4]], dtype=np.float32).reshape(2,2) x2 = np.array([5, 6], dtype=np.float32).reshape(2,1) print('x1=>\n{0}\nx2=>\n{1}'.format(x1, x2)) # matrix product # 矩陣相乘 print() print('x1 product x2=>\n{0}'.format(np.dot(x1, x2))) # element-by-element multiplication # 矩陣內元素相乘 print() print('x1 times x2=>\n{0}'.format(x1*x2)) # transpose # 轉置矩陣 print() print('transpose x1=>\n{0}'.format(np.transpose(x1))) # identity matrix # 單位矩陣 print() print('identify matrix I=>\n{0}'.format(np.eye(3))) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
x1=> [[1. 2.] [3. 4.]] x2=> [[5.] [6.]] x1 product x2=> [[17.] [39.]] x1 times x2=> [[ 5. 10.] [18. 24.]] transpose x1=> [[1. 3.] [2. 4.]] identify matrix I=> [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]] |
重複(重製/repeat, tile)、堆疊(hstack, vstack)
np.repeat(<a>, <repeats>, <axis>)
a:目標矩陣或陣列
repeats:輸入值可以是整數、陣列
axis:為整數,表示執行重製的軸向
將目標矩陣沿著設定的軸向(第一軸 axis = 0)進行重製。
np.tile(<a>, <repeats>)
a:目標矩陣或陣列
repeats:參數為一個tuple
將目標矩陣依 repeats 設定每個維度數值重複執行 n 次,同時沿著各個維度的方向重製。
np.hstack(<array>)
輸入參數內的陣列size必須一致,將輸入的陣列沿著水平方向合併後輸出。
np.vstack(<array>)
輸入參數內的陣列size必須一致,將輸入的陣列沿著垂直方向合併後輸出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
##Repeat / Tile / hstack / vstack col = np.arange(0,3).reshape(3,1) print('col=>\n{0}'.format(col)) # Repeat col for 5 times along the 2nd axis. # 沿著第2軸,重製col 5次 a = np.repeat(col, 5, axis=1) print() print('repeat col for 5 times=>\n{0}'.format(a)) # Repeat col 2 times along the direction of 1st dimension, # and repeat col 4 times along the direction of 2nd dimension. # 沿著第一個維度的方向重複col 2次, 沿著第二個維度的方向重複col 4次. a = np.tile(col, (2,4)) print() print('repeat col like [2,4]=>\n{0}'.format(a)) # Stack col with horizontal line. # 將col沿著水平線堆疊. print() print('hstack col=>\n{0}'.format(np.hstack([col, col]))) # Stack col with vertical line. # 將col沿著垂直線堆疊. print() print('vstack col=>\n{0}'.format(np.vstack([col, col]))) |