对于MATALB用户的NUMPY介绍
python中有许多和matlab比较相似的地方。例如数据处理方面,matlab中有一个函数linsapce,是用来创造等间距的序列的,在numpy库中,也是linsapce。还有绘图方面,在python中,绘制一个子图像,是用pyplotlib中的subplot(324),这与matlab的绘图也比较相似。恰好看到官网对于matlab用户的numpy介绍,小编翻译一下,介绍给大家。原文连接:numpy for matlab users
以下是翻译:
Numpy for Matlab users introduction
一些重要的不同点:
- Matlab中,数据的基本类型是多维双精度的浮点数组。大多数表达式和返回值也都是这个形式。这些2维矩阵运算更像是线性代数的运算。Numpy中,基本类型是多维矩阵,二维矩阵的计算是矩阵内对应元素的运算。然而,array中有一个子类,做特殊的matrix类型的线性运算时,和matlab的运算是一样的线性代数运算。(其实没啥差别,matlab也有元素对应的运算,就是运算符号上有点小差别。)
- Matlab的元素索引从1开始,而python的元素索引从0开始。
- Matlab的脚本语言擅长做线性代数,矩阵的表达式和运算符都比较清晰。但是对于增加GUI和完整应用程序的接口却或多或少是事后诸葛。Numpy是基于python,python从一开始就励志成为一个通用性的编程语言。虽然matlab的一些矩阵控制命令的表达比numpy要好,但是numpy比amtlab能做的更多。比如array的子类可以同时简洁地做array和matrix的运算。
- 在Matlab中,通过值来传递的语义加上懒惰的写时拷贝技术,知道这些拷贝被使用的时候才能创建拷贝。切片运算拷贝了矩阵的部分。在numpy中,array有引用传递的语义,切片操作是矩阵的视图。(不知道在说什么。233333)
Array和Matrix,我该用哪个?
Numpy包含array和matrix类,array类是对于各类数值计算的通用n维矩阵。matrix类是专门为线型计算使用。实际上,只是他们只是各自有一些不同的关键字句柄。
计算符,*,dot(),multiply():
1.对于array类,‘*’是对应元素相乘的,dot()是用来计算矩阵乘法的。
2.对于matrix类,‘*’是矩阵乘法,dot()是对应元素相乘的。
矢量处理(一维矩阵)
对于array类,1xn,nx1和n是不一样的。一维索引如a[:,1]的返回值是n长度的一维的array,而不是一个二维的nx1矩阵。而对于matrix,矩阵的一维索引总是毫无转换的显示为nx1,1xn矩阵。a[:,1]返回nx1的矩阵。
In [5]: a=np.array([[2,34],[54,6]])
In [6]: a[:,1]
Out[6]: array([34, 6])
In [7]: b=np.array([[2,34],[54,6]])
In [8]: b=np.matrix([[2,34],[54,6]])
In [9]: b
Out[9]:
matrix([[ 2, 34],
[54, 6]])
In [10]: b[:,1]
Out[10]:
matrix([[34],
[ 6]])
矩阵多维索引的操作(rank=》2)
array可以操作大于等于2
matrix只能索引2位矩阵
一些方便的特性
array有a.T的特性,返回矩阵的转置。
matrix有a.H,a.I,和a.A的特性。返回共轭转置、逆矩阵和sarray()
方便的构造器
array将python的序列(sequences)作为初始化构造。如array([1,2,3],[2,3,5])
matrix用方便额的字符作为初始化构造,如matrix(“[1 2 4 4 5]”)
两边也都有一些利弊(pros and cons)
array
1) :)将一维的索引根据情况当做列向量或者行向量。如dot(v,A),v是行向量,dot(A,v),v是列向量。这可以使你不用浪费时间打转置。
2} <:(但是矩阵的多次乘法就比较麻烦,dot(dot(A,B),C) vs. AxBxC.
3) :)对应元素相乘很简单,A*B
4) :) array是numpy默认的类型,所以使用最广,也是使用numpy的第三方代码最喜欢返回的类型。
5) :)I是相当于家庭处理数据的任何等级
6) :)如果你熟悉的话,在语义上更接近于张量代数
7) :)所有的运算符都是元素对应的。(*,/,+,…)
matrix
1):\ 更像是MATLAB矩阵
2)<:( 最大维数是2,想要3维矩阵就需要结合python中的list
3)<:( 最小维数也是2,不能有矢量,只能是单行单列的矩阵。
4)<:( NumPy默认类型为array,有些函数即使输入matrix,也会返回array类型。但不应出现在NumPy中,有也是BUG。但是其他第三方代码不会像NumPy一样注重类型的保留。
5):) A*B 是矩阵运算,对于线性代数更适合。
6)<:( 对应元素需要调用函数实现,multipy(A,B).
7)<:( 运算符过载(overloading)的使用有点不合逻辑,比如x不能元素对应运算,但是/是可以元素对应运算的。
所以array更方便使用。
对于matlab使用者的设施
1.包含matrix和一些常见数组结构如ones(),zeros(),empty(),eye(),rand(),repmat()的matlab模块被引入。
2.math has been changed to be a synonym for asmatrix, 而不是matrix,使得可以更简洁的方式将array变成matrix。
3.一些顶层函数被删掉。例如,numpy.rand()现在需要连接到numpy.random.rand(),或者使用matlab模块里的rand()。但是最“numpy”的方式是numpy.random.random(),根据形状提取元组,就像其他numpy函数一样。(which takes a tuple for the shape, like other numpy functions.)
Matlab和NumPy粗略的等同表
首先在python中运行了下面的命令。
from numpy import *
import scipy.linalg
首先介绍array和matrix之间的相互转换。
asarray: 通常返回array对象
asmatrix or mat: 通常返回matrix
asanyarray: 通常返回array对象或其子类,取决输入。例如,如果输入matrix,就返回matrix。
下面的函数对matrix和array两种类型都有效。
General Purpose Equivalents
MATLAB | numpy | Notes |
---|---|---|
help func | info(func) or help(func) or func? (in Ipython) | get help on the function func |
which func | see note HELP | find out where func is defined |
type func | source(func) or func?? (in Ipython) | print source for func (if not a native function) |
a && b | a and b | short-circuiting logical AND operator (Python native operator); scalar arguments only |
a // b | a or b | short-circuiting logical OR operator (Python native operator); scalar arguments only |
1*i, 1*j, 1i, 1j | 1j | complex numbers |
eps | np.spacing(1) | Distance between 1 and the nearest floating point number |
ode45 | scipy.integrate.ode(f).set_integrator(‘dopri5’) | integrate an ODE with Runge-Kutta 4,5 |
ode15s | scipy.integrate.ode(f).set_integrator(‘vode’, method=’bdf’, order=15) | integrate an ODE with BDF method |
Linear Algebra Equivalents
MATLAB | numpy | Notes |
---|---|---|
ndims(a) | ndim(a) or a.ndim | get the number of dimensions of a (tensor rank) |
numel(a) | size(a) or a.size | get the number of elements of an array |
size(a) | shape(a) or a.shape | get the “size” of the matrix |
size(a,n) | a.shape[n-1] | get the number of elements of the n-th dimension of array a. (Note that MATLAB® uses 1 based indexing while Python uses 0 based indexing, See note INDEXING) |
[ 1 2 3; 4 5 6 ] | array([[1.,2.,3.], [4.,5.,6.]]) | 2x3 matrix literal |
[ a b; c d ] | vstack([hstack([a,b]), hstack([c,d])]) or bmat(‘a b; c d’) | .A construct a matrix from blocks a,b,c, and d |
a(end) | a[-1] | access last element in the 1xn matrix a |
a(2,5) | a[1,4] | access element in second row, fifth column |
a(2,:) | a[1] or a[1,:] | entire second row of a |
a(1:5,:) | a[0:5] or a[:5] or a[0:5,:] | the first five rows of a |
a(end-4:end,:) | a[-5:] | the last five rows of a |
a(1:3,5:9) | a[0:3][:,4:9] | rows one to three and columns five to nine of a. This gives read-only access. |
a([2,4,5],[1,3]) | a[ix_([1,3,4],[0,2])] | rows 2,4 and 5 and columns 1 and 3. This allows the matrix to be modified, and doesn’t require a regular slice. |
a(3:2:21,:) | a[ 2:21:2,:] | every other row of a, starting with the third and going to the twenty-first |
a(1:2:end,:) | a[ ::2,:] | every other row of a, starting with the first |
a(end:-1:1,:) or flipud(a) | a[ ::-1,:] | a with rows in reverse order |
a([1:end 1],:) | a[r_[:len(a),0]] | a with copy of the first row appended to the end |
a.’ | a.transpose() or a.T | transpose of a |
a’ | a.conj().transpose() or a.conj().T | conjugate transpose of a |
a * b | a.dot(b) | matrix multiply |
a .* b | a * b | element-wise multiply |
a./b | a/b | element-wise divide |
a.^3 | a**3 | element-wise exponentiation |
(a>0.5) | (a>0.5) | matrix whose i,jth element is (a_ij > 0.5) |
find(a>0.5) | nonzero(a>0.5) | find the indices where (a > 0.5) |
a(:,find(v>0.5)) | a[:,nonzero(v>0.5)[0]] | extract the columms of a where vector v > 0.5 |
a(:,find(v>0.5)) | a[:,v.T>0.5] | extract the columms of a where column vector v > 0.5 |
a(a<0.5)=0 | a[a<0.5]=0 | a with elements less than 0.5 zeroed out |
a .* (a>0.5) | a * (a>0.5) | a with elements less than 0.5 zeroed out |
a(:) = 3 | a[:] = 3 | set all values to the same scalar value |
y=x | y = x.copy() | numpy assigns by reference |
y=x(2,:) | y = x[1,:].copy() | numpy slices are by reference |
y=x(:) | y = x.flatten(1) | turn array into vector (note that this forces a copy) |
1:10 | arange(1.,11.) or r_[1.:11.] or r_[1:10:10j] | create an increasing vector (see note RANGES) |
0:9 | arange(10.) or r_[:10.] or r_[:9:10j] | create an increasing vector (see note RANGES) |
[1:10]’ | arange(1.,11.)[:, newaxis] | create a column vector |
zeros(3,4) | zeros((3,4)) | 3x4 rank-2 array full of 64-bit floating point zeros |
zeros(3,4,5) | zeros((3,4,5)) | 3x4x5 rank-3 array full of 64-bit floating point zeros |
ones(3,4) | ones((3,4)) | 3x4 rank-2 array full of 64-bit floating point ones |
eye(3) | eye(3) | 3x3 identity matrix |
diag(a) | diag(a) | vector of diagonal elements of a |
diag(a,0) | diag(a,0) | square diagonal matrix whose nonzero values are the elements of a |
rand(3,4) | random.rand(3,4) | random 3x4 matrix |
linspace(1,3,4) | linspace(1,3,4) | 4 equally spaced samples between 1 and 3, inclusive |
[x,y]=meshgrid(0:8,0:5) | mgrid[0:9.,0:6.] or meshgrid(r_[0:9.],r_[0:6.] | two 2D arrays: one of x values, the other of y values |
ogrid[0:9.,0:6.] or ix_(r_[0:9.],r_[0:6.] | the best way to eval functions on a grid | |
[x,y]=meshgrid([1,2,4],[2,4,5]) | meshgrid([1,2,4],[2,4,5]) ix_([1,2,4],[2,4,5]) | ix_()the best way to eval functions on a grid |
repmat(a, m, n) | tile(a, (m, n)) | create m by n copies of a |
[a b] | concatenate((a,b),1) or hstack((a,b)) or column_stack((a,b)) or c_[a,b] | concatenate columns of a and b |
[a; b] | concatenate((a,b)) or vstack((a,b)) or r_[a,b] | concatenate rows of a and b |
max(max(a)) | a.max() | maximum element of a (with ndims(a)<=2 for matlab) |
max(a) | a.max(0) | maximum element of each column of matrix a |
max(a,[],2) | a.max(1) | maximum element of each row of matrix a |
max(a,b) | maximum(a, b) | compares a and b element-wise, and returns the maximum value from each pair |
norm(v) | sqrt(dot(v,v)) or np.linalg.norm(v) | L2 norm of vector v |
a & b | logical_and(a,b) | element-by-element AND operator (Numpy ufunc) See note LOGICOPS |
a | b | logical_or(a,b) |
bitand(a,b) | a & b | bitwise AND operator (Python native and Numpy ufunc) |
bitor(a,b) | a | b |
inv(a) | linalg.inv(a) | inverse of square matrix a |
pinv(a) | linalg.pinv(a) | pseudo-inverse of matrix a |
rank(a) | linalg.matrix_rank(a) | rank of a matrix a |
a\b | linalg.solve(a,b) | if a is square; linalg.lstsq(a,b) otherwise |
b/a | Solve a.T x.T = b.T instead | solution of x a = b for x |
[U,S,V]=svd(a) | U, S, Vh = linalg.svd(a), V = Vh.T | singular value decomposition of a |
chol(a) | linalg.cholesky(a).T | cholesky factorization of a matrix (chol(a) in matlab returns an upper triangular matrix, but linalg.cholesky(a) returns a lower triangular matrix) |
[V,D]=eig(a) | D,V = linalg.eig(a) | eigenvalues and eigenvectors of a |
[V,D]=eig(a,b) | V,D = np.linalg.eig(a,b) | eigenvalues and eigenvectors of a,b |
[V,D]=eigs(a,k) | find the k largest eigenvalues and eigenvectors of a | |
[Q,R,P]=qr(a,0) | Q,R = scipy.linalg.qr(a) | QR decomposition |
[L,U,P]=lu(a) | L,U = scipy.linalg.lu(a) or LU,P=scipy.linalg.lu_factor(a) | LU decomposition (note: P(Matlab) == transpose(P(numpy)) ) |
conjgrad | scipy.sparse.linalg.cg | Conjugate gradients solver |
fft(a) | fft(a) | Fourier transform of a |
ifft(a) | ifft(a) | inverse Fourier transform of a |
sort(a) | sort(a) or a.sort() | sort the matrix |
[b,I] = sortrows(a,i) | I = argsort(a[:,i]), b=a[I,:] | sort the rows of the matrix |
regress(y,X) | linalg.lstsq(X,y) | multilinear regression |
decimate(x, q) | scipy.signal.resample(x, len(x)/q) | downsample with low-pass filtering |
unique(a) | unique(a) | |
squeeze(a) | a.squeeze() |
Notes
Submatrix: 对于子矩阵的赋值可以通过使用ix_命令来实现。例如, ind=[1,3]; a[np.ix_(ind,ind)]+=100.
HELP: 没有和Matlab直接对应的help查询命令。但是是有命令可以帮助和列出文件函数的位置。Python也有inspect模型,提供getfile,通常有用。
INDEXING: MATLAB® 使用1作为索引开始,序列最开始为1。而Python使用0开始,所以冲突开始。每个都有优势和缺点。1是序列元素的“开始”,符合人类语言。而0简化了索引。 See also a text by prof.dr. Edsger W. Dijkstra.
RANGES: In MATLAB®, 0:5 可以被用来做范围和切片的语义。然而0:5在Python中,只能作为切片的语义。因而,r_object()被用来使numpy有相似的快速简明的范围结构。r_()并不是像函数或结构体那样,而是像使用方括号的索引形式,允许Python在变量里做切片语义。(不明白这段后面在说什么、)
LOGICOPS: & or | 在numpy中是二进制的与或,但是在matlab里面是逻辑的与或。这点应该每个人都应该非常了解,这对变成效果意义重大。两个运算符可以同时工作,但是优先级有不同。Numpy用函数logical_and/logical_or来表示逻辑与或。
Non-logical {0,1} inputs:对输入进行对应二进制与运算,而matlab对任何非零值当做1处理,进行逻辑与运算。例如,(3&4)在numpy中是0,而matlab是1。
Precedence: Numpy’s &运算符比逻辑运算符(<>)高,而matlab相反。
如果你有逻辑变量,你可以避免使用Numpy的二进制运算符,但是应该小心括号,像z = (x > 1) & (x < 2)。Python的逻辑运算符形式logical_and and logical_or是个不好的设计。
RESHAPE and LINEAR INDEXING: Matlab总是允许用标量和线性指数来索引多维矩阵。numpy并不能。Matlab里的线型指数很常见,如find()返回一个矩阵本身。但是numpy不是。把Matlab代码转换成Python的时候,先要把矩阵变形成线性序列,然后进行指数运算,之后在变回去。当变形过程在同一个储存上产生视图,他们应该会很有效率。Numpy默认是按c的顺序进行变性,而matlab是默认fortran的形式序列。如果只是简单的变成一位在变回去,什么都不影响。但是,如果若果是转换Matlab的源码, z = reshape(x,3,4);numpy中应该这么表示z = x.reshape(3,4,order=’F’)。
Customizing Your Environment
在matlab,唯一建立自己的工作环境的方法是将搜索路径调整到你最喜欢的函数位置。你可以将这个文件保存在startup文件中,Matlab每次启动时都会run它。Python也有相同的模式。
为了让python的搜索路径包括你自己模块的位置,你可以定义自己的环境变量 PYTHONPATH
当Python交互编译器启动的时候,为了让特定的编码启动,你可以定义PYTHONSTARTUP环境变量包括你要启动的编码。
不像Matlab,在Python中,你路径上的东西不能立即调用,必须先import相应文件才可以。
Links
See 这里写链接内容 for another MATLAB®/NumPy cross-reference.
An extensive list of tools for scientific work with python can be found in the topical software page.
MATLAB® and SimuLink® are registered trademarks of The MathWorks.