本文最后更新于 271 天前,其中的信息可能已经过时,如有错误请发送邮件到wuxianglongblog@163.com
从 Matlab 到 Numpy
Numpy 和 Matlab 比较
Numpy
和 Matlab
有很多相似的地方,但 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, Nx1
,A[:,1]
返回的是二维Nx1
矩阵
- 高维数组
array
:支持大于2的维度matrix
:维度只能为2
- 属性
array
:.T
表示转置matrix
:.H
表示复共轭转置,.I
表示逆,.A
表示转化为array
类型
- 构造函数
array
:array
函数接受一个(嵌套)序列作为参数——array([[1,2,3],[4,5,6]])
matrix
:matrix
函数额外支持字符串参数——matrix("[1 2 3; 4 5 6]")
其优缺点各自如下:
-
array
[GOOD]
一维数组既可以看成列向量,也可以看成行向量。v
在dot(A,v)
被看成列向量,在dot(v,A)
中被看成行向量,这样省去了转置的麻烦[BAD!]
矩阵乘法需要使用dot()
函数,如:dot(dot(A,B),C)
vsA*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
:
import numpy
import numpy.matlib
a = numpy.ones(7)
print a.shape
print type(a)
(7L,)
a = numpy.matlib.ones(7)
print a.shape
print type(a)
(1L, 7L)
mat
函数将一个数组转化为矩阵:
a = numpy.array([1,2,3])
b = numpy.mat(a)
print type(b)
有些函数被放到子模块中了,例如调用 rand()
函数需要使用 numpy.random.rand()
(或者从 matlib
模块中生成矩阵):
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
:
from numpy import *
import scipy.linalg
以下 linalg
表示的是 numpy.linalg
,与 scipy.linalg
不同。
注意:MATLAB
与 Numpy
下标之间有这样几处不同:
1-base
vs0-base
()
vs[]
MATLAB
:beg(:step):end
,包含结束值end
Numpy
:beg: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 n 个 a |
[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(...) |
排序 |