從 Matlab 到 Numpy

轉載自:http://lijin-thu.github.io/03.numpy/03.23 from matlab to numpy.html

Numpy 和 Matlab 比較

NumpyMatlab 有很多相似的地方,但 Numpy 並非 Matlab 的克隆,它們之間存在很多差異,例如:

MATLAB® Numpy
基本類型爲雙精度浮點數組,以二維矩陣爲主 基本類型爲 ndarray,有特殊的 matrix
1-based 索引 0-based 索引
腳本主要用於線性代數計算 可以使用其他的 Python 特性
採用值傳遞的方式進行計算
切片返回複製
採用引用傳遞的方式進行計算
切片返回引用
文件名必須和函數名相同 函數可以在任何地方任何文件中定義
收費 免費
2D,3D圖像支持 依賴第三方庫如 matplotlib
完全的編譯環境 依賴於 Python 提供的編譯環境

array 還是 matrix?

Numpy 中不僅提供了 array 這個基本類型,還提供了支持矩陣操作的類 matrix,但是一般推薦使用 array

  • 很多 numpy 函數返回的是 array,不是 matrix
  • array 中,逐元素操作和矩陣操作有着明顯的不同
  • 向量可以不被視爲矩陣

具體說來:

  • *, dot(), multiply()
    • array* -逐元素乘法,dot() -矩陣乘法
    • matrix* -矩陣乘法,multiply() -逐元素乘法
  • 處理向量
    • array:形狀爲 1xN, Nx1, N 的向量的意義是不同的,類似於 A[:,1] 的操作返回的是一維數組,形狀爲 N,一維數組的轉置仍是自己本身
    • matrix:形狀爲 1xN, Nx1A[:,1] 返回的是二維 Nx1 矩陣
  • 高維數組
    • array:支持大於2的維度
    • matrix:維度只能爲2
  • 屬性
    • array.T 表示轉置
    • matrix.H 表示複共軛轉置,.I 表示逆,.A 表示轉化爲 array 類型
  • 構造函數
    • arrayarray 函數接受一個(嵌套)序列作爲參數——array([[1,2,3],[4,5,6]])
    • matrixmatrix 函數額外支持字符串參數——matrix("[1 2 3; 4 5 6]")

其優缺點各自如下:

  • array

    • [GOOD] 一維數組既可以看成列向量,也可以看成行向量。vdot(A,v) 被看成列向量,在 dot(v,A) 中被看成行向量,這樣省去了轉置的麻煩
    • [BAD!] 矩陣乘法需要使用 dot() 函數,如: dot(dot(A,B),C) vs A*B*C
    • [GOOD] 逐元素乘法很簡單: A*B
    • [GOOD] 作爲基本類型,是很多基於 numpy 的第三方庫函數的返回類型
    • [GOOD] 所有的操作 *,/,+,**,... 都是逐元素的
    • [GOOD] 可以處理任意維度的數據
    • [GOOD] 張量運算
  • matrix

    • [GOOD] 類似與 MATLAB 的操作
    • [BAD!] 最高維度爲2
    • [BAD!] 最低維度也爲2
    • [BAD!] 很多函數返回的是 array,即使傳入的參數是 matrix
    • [GOOD] A*B 是矩陣乘法
    • [BAD!] 逐元素乘法需要調用 multiply 函數
    • [BAD!] / 是逐元素操作

當然在實際使用中,二者的使用取決於具體情況。

二者可以互相轉化:

  • asarray :返回數組
  • asmatrix(或者mat) :返回矩陣
  • asanyarray :返回數組或者數組的子類,注意到矩陣是數組的一個子類,所以輸入是矩陣的時候返回的也是矩陣

類 Matlab 函數

有很多類似的函數:

  • ones, zeros, empty, eye, rand, repmat

通常這些函數的返回值是 array,不過 numpy 提供了一個 matlib 的子模塊,子模塊中的這些函數返回值爲 matrix

In [1]:

import numpy
import numpy.matlib

In [2]:

a = numpy.ones(7)

print a.shape
print type(a)
(7L,)
<type 'numpy.ndarray'>

In [3]:

a = numpy.matlib.ones(7)

print a.shape
print type(a)
(1L, 7L)
<class 'numpy.matrixlib.defmatrix.matrix'>

mat 函數將一個數組轉化爲矩陣:

In [4]:

a = numpy.array([1,2,3])

b = numpy.mat(a)

print type(b)
<class 'numpy.matrixlib.defmatrix.matrix'>

有些函數被放到子模塊中了,例如調用 rand() 函數需要使用 numpy.random.rand() (或者從 matlib 模塊中生成矩陣):

In [5]:

a = numpy.random.rand(10)
print a
[ 0.66007267  0.34794294  0.5040946   0.65044648  0.74763248  0.42486999
  0.90922612  0.69071747  0.33541076  0.08570178]

等效操作

假定我們已經這樣導入了 Numpy

In [6]:

from numpy import *
import scipy.linalg

以下 linalg 表示的是 numpy.linalg,與 scipy.linalg 不同。

注意:MATLABNumpy 下標之間有這樣幾處不同:

  • 1-base vs 0-base
  • () vs []
  • MATLABbeg(:step):end,包含結束值 end
  • Numpybeg:end(:step),不包含結束值 end
MATLAB Numpy 註釋
help func info(func)help(func)func?(IPython) 查看函數幫助
which func   查看函數在什麼地方定義
type func source(func)func??(IPython) 查看函數源代碼
a && b a and b 邏輯 AND
1*i, 1*j, 1i, 1j 1j 複數
eps spacing(1) 1 與最近浮點數的距離
ndims(a) ndim(a), a.ndim a 的維數
numel(a) size(a), a.size a 的元素個數
size(a) shape(a), a.shape a 的形狀
size(a,n) a.shape[n-1] 第 n 維的大小
a(2,5) a[1,4] 第 2 行第 5 列元素
a(2,:) a[1], a[1,:] 第 2 行
a(1:5,:) a[0:5] 第 1 至 5 行
a(end-4:end,:) a[-5:] 後 5 行
a(1:3,5:9) a[0:3][:,4:9] 特定行列(1~3 行,5~9 列)
a([2,4,5],[1,3]) a[ix_([1,3,4],[0,2])] 特定行列(2,4,5 行的 1,3 列)
a(3:2:21,:) a[2:21:2,:] 特定行列(3,5,...,21 行)
a(1:2:end,:) a[ ::2,:] 奇數行
a([1:end 1],:) a[r_[:len(a),0]] 將第一行添加到末尾
a.' a.T 轉置
a ./ b a/b 逐元素除法
(a>0.5) (a>0.5) 各個元素是否大於 0.5
find(a>0.5) nonzero(a>0.5) 大於 0.5 的位置
a(a<0.5)=0 a[a<0.5]=0 小於 0.5 的設爲 0
a(:) = 3 a[:] = 3 所有元素設爲 3
y=x y=x.copy() 將 y 設爲 x
y=x(2,:) y=x[1,:].copy() 注意值傳遞和引用傳遞的區別
y=x(:) y=x.flatten(1) 將矩陣變爲一個向量,這裏 1 表示沿着列進行轉化
max(max(a)) a.max() 最大值
max(a) a.max(0) 每一列的最大值
max(a,[],2) a.max(1) 每一行的最大值
max(a,b) maximum(a,b) 逐元素比較,取較大的值
a & b logical_and(a, b) 邏輯 AND
bitand(a, b) a & b 逐比特 AND
inv(a) linalg.inv(a) a 的逆
pinv(a) linalg.inv(a) 僞逆
rank(a) linalg.matrix_rank(a)
a\b linalg.solve(a,b)(如果a是方陣),linalg.lstsq(a,b) a x = b
b/a 求解 a.T x.T = b.T x a = b
[U,S,V]=svd(a) U, S, Vh = linalg.svd(a), V = Vh.T 奇異值分解
chol(a) linalg.cholesky(a).T Cholesky 分解
[V,D]=eig(a) D,V = linalg.eig(a) 特徵值分解
[V,D]=eig(a,b) V,D = scipy.linalg.eig(a,b)  
[V,D]=eigs(a,k)   前 k 大特徵值對應的特徵向量
`` ``  
`` ``  
`` ``  
`` ``  
MATLAB numpy.array numpy.matrix 註釋
[1,2,3;4,5,6] array([[1.,2.,3.],[4.,5.,6.]]) mat([[1.,2.,3.],[4.,5.,6.]]), mat('1,2,3;4,5,6') 2x3 矩陣
[a b;c d] vstack([hstack([a,b]), hsatck([c,d])]]) bmat('a b;c d') 分塊矩陣構造
a(end) a[-1] a[:,-1][0,0] 最後一個元素
a' a.conj().T a.H 複共軛轉置
a * b dot(a,b) a * b 矩陣乘法
a .* b a * b multiply(a,b) 逐元素乘法
a.^3 a**3 power(a,3) 逐元素立方
a(:,find(v>0.5)) a[:,nonzero(v>0.5)[0]] a[:,nonzero(v.A>0.5)[0]] 找出行向量 v>0.5 對應的 a 中的列
a(:,find(v>0.5)) a[:,v.T>0.5] a[:,v.T>0.5)] 找出列向量 v>0.5 對應的 a 中的列
a .* (a>0.5) a * (a>0.5) mat(a.A * (a>0.5).A) 將所有小於 0.5 的元素設爲 0
1:10 arange(1.,11.), r_[1.:11.], r_[1:10:10j] mat(arange(1.,11.)), r_[1.:11., 'r'] 這裏 1. 是爲了將其轉化爲浮點數組
0:9 arange(10.), r_[:10.], r_[:9:10j] mat(arange(10.)), r_[:10., 'r']  
[1:10]' arange(1.,11.)[:,newaxis] r_[1.:11.,'c'] 列向量
zeros, ones, eye, diag, linspace zeros, ones, eye, diag, linspace mat(...)  
rand(3,4) random.rand(3,4) mat(...) 0~1 隨機數
[x,y]=meshgrid(0:8,0:5) mgrid[0:9., 0:6.], meshgrid(r_[0:9.],r_[0:6.]) mat(...) 網格
  ogrid[0:9.,0:6.], ix_(r_[0:9.],r_[0:6.]) mat() 建議在 Numpy 中使用
[x,y]=meshgrid([1,2,4],[2,4,5]) meshgrid([1,2,4],[2,4,5]) mat(...)  
  ix_([1,2,4],[2,4,5]) mat(...)  
repmat(a, m, n) tile(a, (m,n)) mat(...) 產生 m x na
[a b] c_[a,b] concatenate((a,b),1) 列對齊連接
[a; b] r_[a,b] concatenate((a,b)) 行對齊連接
norm(v) sqrt(dot(v,v)), linalg.norm(v) sqrt(dot(v.A,v.A)), linalg.norm(v)
[Q,R,P]=qr(a,0) Q,R = scipy.linalg.qr(a) mat(...) QR 分解
[L,U,P]=lu(a) L,U = Sci.linalg.lu(a) mat(...) LU 分解
fft(a) fft(a) mat(...) FFT
ifft(a) ifft(a) mat(...) IFFT
sort(a) sort(a),a.sort mat(...) 排序

參考:http://wiki.scipy.org/NumPy_for_Matlab_Users#whichNotes

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