1. 程式人生 > >Python矩形轉置transpose--實戰應用詳解

Python矩形轉置transpose--實戰應用詳解

在讀圖片時,會用到這麼的一段程式碼:

image_vector_len = np.prod(image_size)#總元素大小,3*55*47

img = Image.open(path)
        arr_img = np.asarray(img, dtype='float64')
        arr_img = arr_img.transpose(2,0,1).reshape((image_vector_len, ))# 47行,55列,每個點有3個元素rgb。再把這些元素一字排開

transpose是什麼意識呢? 看如下例子:

arr1 = array([[[ 0,  1,  2,  3],

        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
這是原來的矩陣。如果對其進行轉置,執行arr2 = arr1.transpose((1,0,2))
得到:array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

過程是怎樣的?

arr1.shape 應該是(2, 2, 4) 意為 2維,2*4矩陣

arr1.transpose(*args) 裡面的引數,可以這麼理解,他是調換arr1.shape的順序,咱來給arr1.shape標一下角標哈,(2[0], 2[1], 4[2])  [ ] 裡是shape的索引,對吧, 


transpose((1, 0, 2)) 的意思是 按照這個順序 重新設定shape 也就是 (2[1], 2[0], 4[2])

雖然看起來 變換前後的shape都是 2,2,4  , 但是問題來了,transpose是轉置
shape按照(1,0,2)的順序重新設定了, array裡的所有元素 也要按照這個規則重新組成新矩陣

比如 8 在arr1中的索引是 (1, 0, 0)  那麼按照剛才的變換規則,就是 (0, 1, 0) 看看跟你結果arr2的位置一樣了吧,依此類推..

NumPy庫的核心是矩陣及其運算。

使用array()函式可以將python的array_like資料轉變成陣列形式,使用matrix()函式轉變成矩陣形式。

基於習慣,在實際使用中較常用array而少用matrix來表示矩陣。

然後即可使用相關的矩陣運算了

import numpy as np
a = [[1,2,3],[4,5,5],[4,5,5]]

len = a.shape[0] #多維陣列的行數
print(a.dtype) #輸出元素型別
#另外也還可以使用切片方式來處理陣列

然後是涉及到的ufunc(universal function)運算,它是一種能對陣列的每個元素進行操作的函式。NumPy內建的許多ufunc函式都是在C語言級別實現的,因此它們的計算速度非常快。

複製程式碼
1 >>> x = np.linspace(0, 2*np.pi, 10)
2 # 對陣列x中的每個元素進行正弦計算,返回一個同樣大小的新陣列
3 >>> y = np.sin(x)
4 >>> y
5 array([  0.00000000e+00,   6.42787610e-01,   9.84807753e-01,
6          8.66025404e-01,   3.42020143e-01,  -3.42020143e-01,
7         -8.66025404e-01,  -9.84807753e-01,  -6.42787610e-01,
8         -2.44921271e-16])
複製程式碼

有的通用運算函式有:

np.sin()

np.cos()

np.add(a,b)

a.sum(axis=0,1)#axis為0計算全部資料的和,為1則按行計算資料的和

等等其它矩陣可參與的資料計算。

a = array([[1,2,3],[2,3,4]])

array(list): 建立矩陣或高維向量,例如a = array([[0,1,2,3],[4,5,6,7]]),傳入引數也可以是元組

shape: 表示向量大小的元組,例如a.shape結果為tuple,形如(2,3)

ndim: 表示矩陣或高維向量的維數,例如矩陣a的a.ndim為2

size: 表示向量總元素數

itemsize: 表示元素所佔位元組數

nbytes: 表示向量所佔位元組數

real: 所有元素的實部,返回的還是矩陣形式

imag: 所有元素的虛部,返回的還是矩陣形式

flat: 用一維陣列表示矩陣或高維向量(常用於順序遍歷)

T: 表示矩陣的轉置矩陣(也適用於高維向量),例如:a.T

zeros(shape): 建立全0矩陣或高維向量,例如a = zeros((2,3))

ones(shape):建立全1矩陣或高維向量,例如a = ones((2,3))

add(matrix):將矩陣對應元素相加,結果相當於直接用加號

dot(matrix) 
矩陣乘法,注意必須滿足“能乘”的要求 
如果是*,則需注意: 

複製程式碼
 1 aaa = array([[10,9,8],[7,6,5],[42,33,2]])
 2 a = aaa.min(0)  #取每一列的最小值,返回的是一個數組
 3 aaa*aaa#相當於aaa**2:
 4 
 5 #[[ 100,   81,   64],
 6 # [  49,   36,   25],
 7 # [1764, 1089,    4]]
 8 
 9 aaa*a  #aaa每行元素分別與a相乘,結果為
10 
11 #[[ 70,  54,  16],
12 # [ 49,  36,  10],
13 # [294, 198,   4]]
14 
15 a*aaa  #結果與上相同
16 3*aaa  #aaa中每個元素乘以3
複製程式碼

reshape(shape) 
得到改變形狀的矩陣,例如a = array([[1,2,3],[4,5,6]]).reshape((3,2))的結果為[[1,2],[3,4],[5,6]]。注意矩陣的大小不能改變,即reshape的引數表示的矩陣元素數必須等於原矩陣的元素數。 
transpose() 
得到矩陣的轉置矩陣,a.transpose()相當於a.T 
swapaxes(d1,d2) 
調換給定的兩個維度 
flatten() 
返回對應一維向量,例如:

1 aaa = array([[10,9,8],[7,6,5],[42,33,2]])
2 aaa.flatten()
3 #返回值為:
4 array([10,  9,  8,  7,  6,  5, 42, 33,  2])

tolist() 
得到矩陣物件轉化為list的結果

1 aa = aaa.tolist()
2 aa返回為list型(每一行又是一個子list):
3 [[10, 9, 8], [7, 6, 5], [42, 33, 2]]
4 aa[0]  
5 #返回為:
6 [10, 9, 8]

min(axis) 
得到所有元素中的最小值。當給定axis值(min(0)或min(axis=0))時,在該座標上求最小值(得到陣列) 
例如:

複製程式碼
 1 aaa = array([[10,9,8],[7,6,5],[42,33,2]])
 2 aaa.min() 
 3 返回為:aaa矩陣中所有元素的最小值
 4 結果為:2
 5 aaa.min(0) 
 6 返回為:aaa矩陣中所有列中元素的最小值
 7 結果為:array([7, 6, 2])
 8 aaa.min(1)
 9 返回為:aaa矩陣中所有行中元素的最小值
10 結果為:array([8, 5, 2])
複製程式碼

max(axis) 
得到所有元素中的最小值。預設引數axis作用和min()相同 
sum() 
得到陣列元素之和,得到的是一個數字。

也可以aaa.sum(axis),分別求每一行或者是每一列的元素之和

cumsum() 
得到累計和,即依次加一個元素求和的一維陣列。 
例如:

1 aaa.cumsum()
2 結果為:array([ 10,  19,  27,  34,  40,  45,  87, 120, 122])

prod() 
得到陣列所有元素之積,是個數字。也可以aaa.sum(axis),分別求每一行或者是每一列的元素之積

cumprod() 
得到累計積,例子形式與上面cumsum()相同,這兩個函式也都可以分座標累計加和累計乘。 
mean() 
得到元素的平均數 
all() 
如果所有元素為真,返回真;否則返回假 
any() 
如果所有元素只要有一個真,返回真;否則返回假。 
特徵值 
linalg.eigvals() 
返回A的特徵值 
linalg.eig(A) 
返回A的特徵值和特徵向量,例如(eval, evec) = linalg.eig(A),其中eval的對角元為A的各個特徵值,evec對應各列是相應特徵向量。

複製程式碼
 1 >>> a = array([[-1,1,0],
 2                [-4,3,0],
 3                [ 1,0,2]])
 4 >>> eval, evec = linalg.eig(a)
 5 >>> eval
 6 array([ 2.,  1.,  1.])
 7 >>> evec
 8 array([[ 0.        ,  0.40824829,  0.40824829],
 9        [ 0.        ,  0.81649658,  0.81649658],
10        [ 1.        , -0.40824829, -0.40824829]])
複製程式碼

即特徵向量為λ1=2的(0,0,1)和λ2=λ3=1的(0.4,0.8,-0.4)