MATLAB®和NumPy有很多共同点,但是NumPy的创建是为了与Python一起工作,而不是作为MATLAB的克隆。本指南将帮助MATLAB用户开始使用NumPy。
在MATLAB中,基本类型(即使是标量)也是多维数组。MATLAB中的数组指定存储为双精度浮点数的2D数组,除非指定维数和类型。对这些阵列的二维实例的操作是线性代数中矩阵操作的模型。
在NumPy中,基本类型是多维的 array . NumPy中的数组分配通常存储为 n-dimensional arrays 具有按顺序容纳对象所需的最小类型,除非指定尺寸和类型的数目。NumPy逐元素执行操作,因此将2D数组与 * 不是矩阵乘法,而是元素对元素的乘法。(The) @ 运算符,从python3.5开始就可用,可以用于传统的矩阵乘法。)
array
*
@
MATLAB从1开始计算指数; a(1) 是第一个元素。 See note INDEXING
a(1)
NumPy和Python一样,从0开始计算索引; a[0] 是第一个元素。
a[0]
MATLAB的脚本语言是为线性代数创建的,因此一些数组操作的语法比NumPy的更简洁。另一方面,添加gui和创建完整应用程序的API或多或少是事后才想到的。
NumPy是基于Python的,Python是一种通用语言。NumPy的优点是可以访问Python库,包括: SciPy , Matplotlib , Pandas , OpenCV ,等等。此外,Python经常 embedded as a scripting language 在其他软件中,也允许在那里使用NumPy。
MATLAB数组切片使用传递值语义,并使用延迟的写时拷贝方案,以防止在需要拷贝之前创建拷贝。切片操作复制阵列的一部分。
NumPy数组切片使用按引用传递,它不复制参数。切片操作是将视图放入数组中。
下表给出了一些常用MATLAB表达式的粗略等价物。这些是类似的表达,而不是等价的表达。有关详细信息,请参阅 documentation .
在下表中,假设您已在python中执行了以下命令:
import numpy as np from scipy import io, integrate, linalg, signal from scipy.sparse.linalg import eigs
另外,假设下面的注释是关于“矩阵”的,那么参数是二维实体。
MATLAB
NumPy
笔记
help func
info(func) 或 help(func) 或 func? (在伊皮顿)
info(func)
help(func)
func?
获取有关函数的帮助 func
which func
see note HELP
找出哪里 func 定义
type func
np.source(func) 或 func?? (在伊皮顿)
np.source(func)
func??
的打印源 func (如果不是本机函数)
% comment
# comment
用文本注释一行代码 comment
comment
for i=1:3 fprintf('%i\n',i) end
for i in range(1, 4): print(i)
使用for循环打印数字1、2和3 range
range
a && b
a and b
短路逻辑与运算符 (Python native operator );仅标量参数
a || b
a or b
短路逻辑或运算符 (Python native operator );仅标量参数
>> 4 == 4 ans = 1 >> 4 == 5 ans = 0
>>> 4 == 4 True >>> 4 == 5 False
这个 boolean objects 在Python中 True 和 False ,而不是MATLAB的逻辑类型 1 和 0 .
True
False
1
0
a=4 if a==4 fprintf('a = 4\n') elseif a==5 fprintf('a = 5\n') end
a = 4 if a == 4: print('a = 4') elif a == 5: print('a = 5')
创建if else语句以检查 a 为4或5并打印结果
a
1*i, 1*j, 1i, 1j
1*i
1*j
1i
1j
复数
eps
np.finfo(float).eps or np.spacing(1)
np.finfo(float).eps
np.spacing(1)
64位浮点运算中舍入引起的相对误差的上限。
load data.mat
io.loadmat('data.mat')
加载保存到文件中的MATLAB变量 data.mat . (注意:将数组保存到 data.mat 在MATLAB/Octave中,使用最新的二进制格式。 scipy.io.loadmat 将创建一个包含已保存数组和其他信息的字典。)
data.mat
scipy.io.loadmat
ode45
integrate.solve_ivp(f)
将ODE与Runge Kutta 4,5集成
ode15s
integrate.solve_ivp(f, method='BDF')
将ODE与BDF方法集成
ndims(a)
np.ndim(a) or a.ndim
np.ndim(a)
a.ndim
数组维数 a
numel(a)
np.size(a) or a.size
np.size(a)
a.size
数组元素数 a
size(a)
np.shape(a) or a.shape
np.shape(a)
a.shape
数组的“大小” a
size(a,n)
a.shape[n-1]
获取数组第n维的元素数 a . (请注意,MATLAB使用基于1的索引,而Python使用基于0的索引,请参见注释) INDEXING )
[ 1 2 3; 4 5 6 ]
np.array([[1. ,2. ,3.], [4. ,5. ,6.]])
定义2x3 2D阵列
[ a b; c d ]
np.block([[a, b], [c, d]])
从块构造矩阵 a , b , c 和 d
b
c
d
a(end)
a[-1]
访问MATLAB向量(1xn或nx1)或1D NumPy数组中的最后一个元素 a (长度n)
a(2,5)
a[1, 4]
访问2D数组第二行第五列中的元素 a
a(2,:)
a[1] or a[1, :]
a[1]
a[1, :]
整个二维数组的第二行 a
a(1:5,:)
a[0:5] or a[:5] or a[0:5, :]
a[0:5]
a[:5]
a[0:5, :]
二维数组的前5行 a
a(end-4:end,:)
a[-5:]
2D数组的最后5行 a
a(1:3,5:9)
a[0:3, 4:9]
二维数组的第一到第三行和第五到第九列, a .
a([2,4,5],[1,3])
a[np.ix_([1, 3, 4], [0, 2])]
第2、4、5行和第1、3列。这样就可以修改矩阵,而不需要常规切片。
a(3:2:21,:)
a[2:21:2,:]
每隔一行 a 从第三个开始到第二十一个
a(1:2:end,:)
a[ ::2,:]
每隔一行 a ,从第一个开始
a(end:-1:1,:) or flipud(a)
a(end:-1:1,:)
flipud(a)
a[::-1,:]
a 行的顺序相反
a([1:end 1],:)
a[np.r_[:len(a),0]]
a 在末尾附加第一行的副本
a.'
a.transpose() or a.T
a.transpose()
a.T
转置 a
a'
a.conj().transpose() or a.conj().T
a.conj().transpose()
a.conj().T
共轭转座 a
a * b
a @ b
矩阵乘法
a .* b
元素相乘
a./b
a/b
按元素划分
a.^3
a**3
元素求幂
(a > 0.5)
i,jth元素为(a_ij>0.5)的矩阵。MATLAB结果是逻辑值0和1的数组。NumPy结果是一个布尔值数组 False 和 True .
find(a > 0.5)
np.nonzero(a > 0.5)
查找索引 (a > 0.5)
a(:,find(v > 0.5))
a[:,np.nonzero(v > 0.5)[0]]
提取…的柱状物 a 其中矢量v>0.5
a(:,find(v>0.5))
a[:, v.T > 0.5]
提取…的柱状物 a 其中,列向量v>0.5
a(a<0.5)=0
a[a < 0.5]=0
a 元素小于0.5归零
a .* (a>0.5)
a * (a > 0.5)
a(:) = 3
a[:] = 3
将所有值设置为相同的标量值
y=x
y = x.copy()
NumPy通过引用指定
y=x(2,:)
y = x[1, :].copy()
NumPy切片仅供参考
y=x(:)
y = x.flatten()
将数组转换为向量(请注意,这会强制创建一个副本)。要获得与MATLAB中相同的数据顺序,请使用 x.flatten('F') .
x.flatten('F')
1:10
np.arange(1., 11.) or np.r_[1.:11.] or np.r_[1:10:10j]
np.arange(1., 11.)
np.r_[1.:11.]
np.r_[1:10:10j]
创建一个递增向量(参见注释 RANGES )
0:9
np.arange(10.) or np.r_[:10.] or np.r_[:9:10j]
np.arange(10.)
np.r_[:10.]
np.r_[:9:10j]
[1:10]'
np.arange(1.,11.)[:, np.newaxis]
创建列向量
zeros(3,4)
np.zeros((3, 4))
3x4二维数组,包含64位浮点零
zeros(3,4,5)
np.zeros((3, 4, 5))
3x4x5三维数组,包含64位浮点零
ones(3,4)
np.ones((3, 4))
3x4二维数组,包含64位浮点型
eye(3)
np.eye(3)
3x3单位矩阵
diag(a)
np.diag(a)
返回2D数组对角线元素的向量, a
diag(v,0)
np.diag(v, 0)
返回一个非零值为向量元素的平方对角矩阵, v
v
rng(42,'twister') rand(3,4)
from numpy.random import default_rng rng = default_rng(42) rng.random(3, 4)
或旧版本: random.rand((3, 4))
random.rand((3, 4))
使用默认的随机数生成器和seed=42生成一个随机3x4数组
linspace(1,3,4)
np.linspace(1,3,4)
4个等距样品,介于1和3之间,包括
[x,y]=meshgrid(0:8,0:5)
np.mgrid[0:9.,0:6.] or np.meshgrid(r_[0:9.],r_[0:6.]
np.mgrid[0:9.,0:6.]
np.meshgrid(r_[0:9.],r_[0:6.]
两个二维数组:一个是x值,另一个是y值
ogrid[0:9.,0:6.] or np.ix_(np.r_[0:9.],np.r_[0:6.]
ogrid[0:9.,0:6.]
np.ix_(np.r_[0:9.],np.r_[0:6.]
在网格上评估函数的最佳方法
[x,y]=meshgrid([1,2,4],[2,4,5])
np.meshgrid([1,2,4],[2,4,5])
ix_([1,2,4],[2,4,5])
repmat(a, m, n)
np.tile(a, (m, n))
创建m x n个副本 a
[a b]
np.concatenate((a,b),1) or np.hstack((a,b)) or np.column_stack((a,b)) or np.c_[a,b]
np.concatenate((a,b),1)
np.hstack((a,b))
np.column_stack((a,b))
np.c_[a,b]
连接的列 a 和 b
[a; b]
np.concatenate((a,b)) or np.vstack((a,b)) or np.r_[a,b]
np.concatenate((a,b))
np.vstack((a,b))
np.r_[a,b]
连接的行 a 和 b
max(max(a))
a.max() or np.nanmax(a)
a.max()
np.nanmax(a)
的最大元素 a (对于MATLAB,ndims(a)<=2,如果存在NaN, nanmax 将忽略这些并返回最大值)
nanmax
max(a)
a.max(0)
数组每列的最大元素 a
max(a,[],2)
a.max(1)
数组每行的最大元素数 a
max(a,b)
np.maximum(a, b)
比较 a 和 b 并返回每对的最大值
norm(v)
np.sqrt(v @ v) or np.linalg.norm(v)
np.sqrt(v @ v)
np.linalg.norm(v)
向量的l2范数 v
a & b
logical_and(a,b)
逐元素和运算符(numpy ufunc) See note LOGICOPS
a | b
np.logical_or(a,b)
逐元素或运算符(numpy ufunc) See note LOGICOPS
bitand(a,b)
位与运算符(python-native和numpy-ufunc)
bitor(a,b)
按位或运算符(python-native和numpy-ufunc)
inv(a)
linalg.inv(a)
二维方阵的逆 a
pinv(a)
linalg.pinv(a)
二维阵列的伪逆 a
rank(a)
linalg.matrix_rank(a)
二维阵列的矩阵秩 a
a\b
linalg.solve(a, b) 如果 a 是正方形的; linalg.lstsq(a, b) 否则
linalg.solve(a, b)
linalg.lstsq(a, b)
对于x,a x=b的解
b/a
解决 a.T x.T = b.T 相反
a.T x.T = b.T
x的解a=b,x的解
[U,S,V]=svd(a)
U, S, Vh = linalg.svd(a), V = Vh.T
奇异值分解 a
c=chol(a) where a==c'*c
c=chol(a)
a==c'*c
c = linalg.cholesky(a) where a == c@c.T
c = linalg.cholesky(a)
a == c@c.T
二维阵列的Cholesky分解 (chol(a) 在MATLAB中,返回一个上三角二维数组,但是 cholesky 返回下三角(二维数组)
chol(a)
cholesky
[V,D]=eig(a)
D,V = linalg.eig(a)
特征值 和特征向量 属于 a 在哪里
[V,D]=eig(a,b)
D,V = linalg.eig(a, b)
特征值 和特征向量 属于 a , b 在哪里?
[V,D]=eigs(a,3)
D,V = eigs(a, k = 3)
找到 k=3 二维阵列的最大特征值和特征向量, a
k=3
[Q,R,P]=qr(a,0)
Q,R = linalg.qr(a)
QR分解
[L,U,P]=lu(a) where a==P'*L*U
[L,U,P]=lu(a)
a==P'*L*U
P,L,U = linalg.lu(a) where a == P@L@U
P,L,U = linalg.lu(a)
a == P@L@U
LU分解(注:P(MATLAB)==转置(P(NumPy)))
conjgrad
cg
共轭梯度解算器
fft(a)
np.fft(a)
傅立叶变换 a
ifft(a)
np.ifft(a)
反傅立叶变换 a
sort(a)
np.sort(a) or a.sort(axis=0)
np.sort(a)
a.sort(axis=0)
对二维数组的每一列进行排序, a
sort(a, 2)
np.sort(a, axis = 1) or a.sort(axis = 1)
np.sort(a, axis = 1)
a.sort(axis = 1)
对2D数组的每一行进行排序, a
[b,I]=sortrows(a,1)
I = np.argsort(a[:, 0]); b = a[I,:]
保存数组 a 作为数组 b 按第一列排序的行
x = Z\y
x = linalg.lstsq(Z, y)
对表格进行线性回归
decimate(x, q)
signal.resample(x, np.ceil(len(x)/q))
低通滤波下采样
unique(a)
np.unique(a)
数组中唯一值的向量 a
squeeze(a)
a.squeeze()
删除数组的单例维数 a . 请注意,MATLAB将始终返回2D或更高的数组,而NumPy将返回0D或更高的数组
子矩阵 :可以使用 ix_ 命令。E、 例如,对于二维阵列 a 人们可能会这样做: ind=[1, 3]; a[np.ix_(ind, ind)] += 100 .
ix_
ind=[1, 3]; a[np.ix_(ind, ind)] += 100
HELP :没有直接等效的matlab which 命令,但是命令 help 和 numpy.source 通常会列出函数所在的文件名。python也有一个 inspect 模块(DO) import inspect )它提供了 getfile 这经常奏效。
which
help
numpy.source
inspect
import inspect
getfile
INDEXING :MATLAB使用基于一的索引,因此序列的初始元素具有索引1。Python使用基于零的索引,因此序列的初始元素的索引为0。混乱和战争的产生是因为它们各有利弊。基于One的索引与人类常见的语言用法是一致的,即序列的“第一个”元素具有索引1。基于零的索引 simplifies indexing . 也见 a text by prof.dr. Edsger W. Dijkstra .
RANGES :在MATLAB中, 0:5 可以同时用作范围文本和“切片”索引(在括号内);但是,在Python中,构造如下 0:5 可以 only 用作切片索引(在方括号内)。所以有点古怪 r_ 对象的创建允许NumPy具有类似的简洁范围构造机制。请注意 r_ 不是像函数或构造函数那样调用,而是 索引的 使用方括号,这允许在参数中使用python的slice语法。
0:5
r_
LOGICOPS : & or | in NumPy is bitwise AND/OR, while in MATLAB & and | are logical AND/OR. The two can appear to work the same, but there are important differences. If you would have used MATLAB's & or | operators, you should use the NumPy ufuncs logical_and/logical_or . MATLAB与NumPy的显著差异 & 和 | 操作员包括:
&
|
logical_and
logical_or
Non-logical {0,1} inputs: NumPy's output is the bitwise AND of the inputs. MATLAB treats any non-zero value as 1 and returns the logical AND. For example (3 & 4) in NumPy is 0, while in MATLAB both 3 and 4 are considered logical true and (3 & 4) returns 1.
(3 & 4)
3
4
优先级:NumPy的&operator的优先级高于逻辑运算符,如 < 和 > MATLAB则相反。
<
>
如果您知道自己有布尔参数,可以不使用NumPy的位运算符,但要小心使用括号,如下所示: z = (x > 1) & (x < 2) . 无NumPy运算符的形式 logical_and 和 logical_or 是Python设计的不幸结果。
z = (x > 1) & (x < 2)
重塑和线性索引 :MATLAB始终允许使用标量或线性索引访问多维数组,NumPy则不允许。线性指标在MATLAB程序中很常见。 find() 在矩阵上返回它们,而NumPy的find的行为则不同。在转换MATLAB代码时,可能需要首先将矩阵重塑为线性序列,执行一些索引操作,然后再重塑回来。由于重塑(通常)会在同一个存储上生成视图,因此应该可以相当有效地执行此操作。注意,NumPy中reformate使用的扫描顺序默认为“C”顺序,而MATLAB使用Fortran顺序。如果你只是简单地转换成一个线性序列然后返回,这并不重要。但是,如果您要从依赖于扫描顺序的MATLAB代码转换重塑,则此MATLAB代码: z = reshape(x,3,4); 应该成为 z = x.reshape(3,4,order='F').copy() 在 NumPy 。
find()
z = reshape(x,3,4);
z = x.reshape(3,4,order='F').copy()
过去,numpy提供了一种特殊的矩阵类型, np.matrix 它是ndarray的一个子类,它使二元运算成为线性代数运算。您可能会看到它在某些现有代码中使用,而不是 np.array . 那么,使用哪一个呢?
使用数组 .
它们支持MATLAB支持的多维数组代数
它们是NumPy的标准向量/矩阵/张量类型。许多NumPy函数返回数组,而不是矩阵。
元素运算和线性代数运算之间有着明显的区别。
如果愿意,您可以使用标准向量或行/列向量。
在Python3.5之前,使用数组类型的唯一缺点是必须使用 dot 而不是 * 乘(减)两个张量(标量积、矩阵矢量乘等)。由于python 3.5,您可以使用矩阵乘法 @ 操作员。
dot
鉴于上述情况,我们打算取消预测 matrix 最终。
matrix
numpy包含两个 array 类与A matrix 班级。这个 array 类是用于多种数值计算的通用N维数组,而 matrix 专门用于促进线性代数计算。实际上,两者之间只有少数几个关键区别。
算子 * 和 @ 功能 dot() 和 multiply() :
dot()
multiply()
为了 array , ``*`` means element-wise multiplication ,同时 ``@`` means matrix multiplication ;它们具有相关功能 multiply() 和 dot() . (在Python 3.5之前, @ 不存在,必须使用 dot() 用于矩阵乘法)。
为了 matrix , ``*`` means matrix multiplication 对于元素乘法,必须使用 multiply() 功能。
向量处理(一维数组)
为了 array , the 矢量形状1Xn、nx1和n都是不同的。 . 像这样的操作 A[:,1] 返回形状n的一维数组,而不是形状nx1的二维数组。一维转置 array 什么也不做。
A[:,1]
为了 matrix , one-dimensional arrays are always upconverted to 1xN or Nx1 matrices (行或列向量)。 A[:,1] 返回形状为nx1的二维矩阵。
高维阵列的处理(ndim>2)
array 物体 can have number of dimensions > 2 ;
matrix 物体 总是有精确的二维 .
便利性属性
array 具有.t属性 ,返回数据的转置。
matrix 还具有.h、.i和.a属性 ,返回共轭转置、反转和 asarray() 分别是矩阵的。
asarray()
方便施工人员
这个 array 构造函数 将(嵌套)python序列作为初始值设定项 . 如 array([[1,2,3],[4,5,6]]) .
array([[1,2,3],[4,5,6]])
这个 matrix 另外,建造商 采用方便的字符串初始值设定项 . 如在 matrix("[1 2 3; 4 5 6]") .
matrix("[1 2 3; 4 5 6]")
使用这两种方法有利弊:
:) 元素相乘很容易: A*B .
:)
A*B
:( 你必须记住,矩阵乘法有它自己的算符, @ .
:(
:) 可以将一维数组视为 任何一个 行或列向量。 A @ v 对待 v 作为列向量,而 v @ A 对待 v 作为行向量。这样可以省去很多转置操作。
A @ v
v @ A
:) array 是“默认”numpy类型,因此它得到最多的测试,并且是最有可能由使用numpy的第三方代码返回的类型。
:) 在家里处理任何尺寸的数据。
:) 如果你熟悉的话,在语义上更接近张量代数。
:) All operations (*, /, `` + - 等等)是元素方面的。
/
-
:( 稀疏矩阵来自 scipy.sparse 不要与数组进行很好的交互。
scipy.sparse
:\\ 行为更像MATLAB矩阵。
:\\
<:( 二维的最大值。保存所需的三维数据 array 或者是一个python列表 matrix .
<:(
<:( 二维的最小值。你不能有向量。它们必须转换为单列或单行矩阵。
<:( 自从 array 是numpy中的默认值,某些函数可能返回 array 即使你给他们一个 matrix 作为一个论点。这种情况不应该发生在numpy函数中(如果是bug),但是基于numpy的第三方代码可能不像numpy那样支持类型保护。
:) A*B 是矩阵乘法,所以它看起来就像是用线性代数写的(对于python>=3.5普通数组来说,使用 @ 操作员)。
<:( 元素乘法需要调用一个函数, multiply(A,B) .
multiply(A,B)
<:( 使用运算符重载有点不合逻辑: * 不以要素为导向,但 / 做。
与…互动 scipy.sparse 有点干净。
这个 array 因此更适合使用。事实上,我们打算贬低 matrix 最终。
在MATLAB中,可用于定制环境的主要工具是用您喜欢的函数的位置修改搜索路径。您可以将这些自定义设置放入启动脚本中,以便MATLAB在启动时运行。
numpy,或者更确切地说是python,有类似的功能。
要修改python搜索路径以包含自己模块的位置,请定义 PYTHONPATH 环境变量。
PYTHONPATH
要在启动交互式Python解释器时执行特定的脚本文件,请定义 PYTHONSTARTUP 包含启动脚本名称的环境变量。
PYTHONSTARTUP
与MATLAB不同,在MATLAB中可以立即调用路径上的任何内容,使用Python时,需要首先执行“import”语句,以使特定文件中的函数可访问。
例如,您可能会制作一个这样的启动脚本(注意:这只是一个示例,而不是“最佳实践”的声明):
# Make all numpy available via shorter 'np' prefix import numpy as np # # Make the SciPy linear algebra functions available as linalg.func() # e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution) from scipy import linalg # # Define a Hermitian function def hermitian(A, **kwargs): return np.conj(A,**kwargs).T # Make a shortcut for hermitian: # hermitian(A) --> H(A) H = hermitian
使用不推荐的 matrix 等 matlib 功能:
# Make all matlib functions accessible at the top level via M.func() import numpy.matlib as M # Make some matlib functions accessible directly at the top level via, e.g. rand(3,3) from numpy.matlib import matrix,rand,zeros,ones,empty,eye
另一个有些过时的MATLAB/NumPy交叉引用可以在http://mathesaurus.sf.net/
可以在 topical software page .
见 List of Python software: scripting 使用Python作为脚本语言的软件列表
MATLAB®和SimuLink®是MathWorks,Inc.的注册商标。