基础与用法
NumPy 基础知识
这些文档阐明了 NumPy 中的概念、设计决策和技术限制。这是了解 NumPy 基本思想和哲学的好地方。
MATLAB 用户的 NumPy
介绍
MATLAB® 和 NumPy 有很多共同之处,但 NumPy 是为了与 Python 一起使用而创建的,而不是 MATLAB 的克隆。本指南将帮助 MATLAB 用户开始使用 NumPy。
一些主要区别
在 MATLAB 中,即使对于标量,基本类型也是多维数组。在 MATLAB 中的数组赋值都以双精度浮点数的 2D 数组存储,除非你指定维数和类型。对这些数组的 2D 实例的操作都是模仿线性代数中的矩阵操作。 | 在 NumPy 中,基本类型是多维数组 。在 NumPy 中的数组赋值通常存储为 n 维数组,只需要最小类型来存储对象,除非你指定维数和类型。NumPy 执行元素按元素的操作,所以用* 来乘以 2D 数组不是矩阵乘法 - 这是元素按元素的乘法。(自 Python 3.5 开始,可以使用@ 运算符进行传统的矩阵乘法。) |
MATLAB 数字从 1 开始索引;a(1) 是第一个元素。参见说明 索引 |
NumPy,与 Python 一样,数字从 0 开始索引;a[0] 是第一个元素。 |
MATLAB 的脚本语言是为了线性代数而创建的,因此一些数组操作的语法比 NumPy 更紧凑。另一方面,添加 GUI 和创建完整的应用程序的 API 更多或多或少是事后想法。 | NumPy 是基于 Python 的通用语言。NumPy 的优势在于访问 Python 库,包括:SciPy,Matplotlib,Pandas,OpenCV等。此外,Python 经常作为嵌入式脚本语言嵌入到其他软件中,也可以在那里使用 NumPy。 |
MATLAB 数组切片使用值传递语义,采用延迟写入复制方案以防止创建副本,直到需要为止。切片操作复制数组的部分。 | NumPy 数组切片使用按引用传递的方式,不复制参数。切片操作是对数组的视图。 |
大致等效项
下表提供了一些常见 MATLAB 表达式的大致等效项。这些是类似的表达式,而不是等效项。详情请参见文档。
在下表中,假设你已经在 Python 中执行了以下命令:
import numpy as np from scipy import io, integrate, linalg, signal from scipy.sparse.linalg import cg, eigs
还假设如果备注谈论“矩阵”,那么参数是二维实体。
通用等效物
MATLAB | NumPy | 说明 |
help func |
info(func) 或 help(func) 或 func? (在 IPython 中) |
获取关于函数 func 的帮助信息 |
which func |
参见注释 HELP | 找出 func 的定义位置 |
type func |
np.source(func) 或 func?? (在 IPython 中) |
输出 func 的源代码(如果不是原生函数) |
% comment |
# comment |
在代码行中注释文本comment |
|
for i=1:3 fprintf('%i\n',i) end
|
for i in range(1, 4): print(i)
使用 for 循环使用 range 打印数字 1, 2 和 3 |
a && b |
a || b |
|
>> 4 == 4 ans = 1 >> 4 == 5 ans = 0
|
>>> 4 == 4 True >>> 4 == 5 False
Python 中的布尔对象为 True 和 False ,而不是 MATLAB 的逻辑类型 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 并打印结果 |
1*i , 1*j , 1i , 1j |
eps |
load data.mat |
ode45 |
ode15s |
线性代数等价操作
MATLAB | NumPy | 备注 |
ndims(a) |
np.ndim(a) 或 a.ndim |
数组 a 的维数 |
numel(a) |
np.size(a) 或 a.size |
数组 a 的元素数量 |
size(a) |
np.shape(a) 或 a.shape |
数组 a 的“大小” |
size(a,n) |
a.shape[n-1] |
获取数组 a 的第 n 维的元素数量。(注意 MATLAB 使用基于 1 的索引,而 Python 使用基于 0 的索引,参见 INDEXING 注释) |
[ 1 2 3; 4 5 6 ] |
np.array([[1., 2., 3.], [4., 5., 6.]]) |
定义一个 2x3 的二维数组 |
[ a b; c d ] |
np.block([[a, b], [c, d]]) |
从块 a , b , c 和 d 构建矩阵 |
a(end) |
a[-1] |
访问 MATLAB 向量(1xn 或 nx1)或 1D NumPy 数组 a (长度 n)中的最后一个元素 |
a(2,5) |
a[1, 4] |
访问二维数组 a 中第二行第五列的元素 |
a(2,:) |
a[1] 或 a[1, :] |
二维数组 a 的整个第二行 |
a(1:5,:) |
a[0:5] 或 a[:5] 或 a[0:5, :] |
二维数组 a 的前 5 行 |
a(end-4:end,:) |
a[-5:] |
二维数组 a 的最后 5 行 |
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,:) 或 flipud(a) |
a[::-1,:] |
a 的行顺序反转 |
a([1:end 1],:) |
a[np.r_[:len(a),0]] |
a 的复制,将第一行附加到末尾 |
a.' |
a.transpose() 或 a.T |
a 的转置 |
a' |
a.conj().transpose() 或 a.conj().T |
a 的共轭转置 |
a * b |
a @ b |
矩阵相乘 |
a .* b |
a * b |
逐元素相乘 |
a./b |
a/b |
逐元素除 |
a.³ |
a**3 |
逐元素求幂 |
(a > 0.5) |
(a > 0.5) |
矩阵的第 i,j 个元素为 (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 中小于 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') 。 |
1:10 |
np.arange(1., 11.) 或 np.r_[1.:11.] 或 np.r_[1:10:10j] |
创建递增向量(见注释 RANGES) |
0:9 |
np.arange(10.) 或 np.r_[:10.] 或 np.r_[:9:10j] |
创建递增向量(见注释 RANGES) |
[1:10]' |
np.arange(1.,11.)[:, np.newaxis] |
创建列向量 |
zeros(3,4) |
np.zeros((3, 4)) |
64 位浮点 0 组成的 3x4 二维数组 |
zeros(3,4,5) |
np.zeros((3, 4, 5)) |
64 位浮点 0 组成的 3x4x5 三维数组 |
ones(3,4) |
np.ones((3, 4)) |
64 位浮点 1 组成的 3x4 二维数组 |
eye(3) |
np.eye(3) |
3x3 单位矩阵 |
diag(a) |
np.diag(a) |
返回二维数组 a 的对角元素向量 |
diag(v,0) |
np.diag(v, 0) |
返回一个正方形对角阵,其非零值是向量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))
| 用默认随机数生成器和 seed = 42 生成一个 3x4 的随机数组 |
linspace(1,3,4) |
np.linspace(1,3,4) |
在 1 和 3 之间生成 4 个等间距的样本,包括边界值 |
[x,y]=meshgrid(0:8,0:5) |
np.mgrid[0:9.,0:6.] 或np.meshgrid(r_[0:9.],r_[0:6.]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
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]) |
|
np.ix_([1,2,4],[2,4,5]) |
在网格上评估函数的最佳方法 | |
repmat(a, m, n) |
np.tile(a, (m, n)) |
创建 m 行 n 列的a 副本 |
[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)) 或np.vstack((a,b)) 或np.r_[a,b] |
连接a 和b 的行 |
max(max(a)) |
a.max() 或np.nanmax(a) |
a 的最大元素(对于 MATLAB,如果存在 NaN 值,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) 或np.linalg.norm(v) |
向量v 的 L2 范数 |
a & b |
logical_and(a,b) |
逐元素的与运算符(NumPy ufunc)查看逻辑运算符注意事项 |
a | b |
np.logical_or(a,b) |
逐元素的或运算符(NumPy ufunc)查看逻辑运算符注意事项 |
bitand(a,b) |
a & b |
位与运算符(Python 原生和 NumPy ufunc) |
bitor(a,b) |
a | b |
位或运算符(Python 原生和 NumPy ufunc) |
inv(a) |
linalg.inv(a) |
二维方阵a 的逆矩阵 |
pinv(a) |
linalg.pinv(a) |
二维数组a 的伪逆矩阵 |
rank(a) |
np.linalg.matrix_rank(a) |
二维数组a 的矩阵秩 |
a\b |
如果a 是方阵,则linalg.solve(a, b) ;否则为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 |
a 的奇异值分解 |
chol(a) |
linalg.cholesky(a) |
二维数组a 的 Cholesky 分解 |
[V,D]=eig(a) |
D,V = linalg.eig(a) |
a 的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda v) |
[V,D]=eig(a,b) |
D,V = linalg.eig(a, b) |
a , b 的特征值(\lambda)和特征向量(v),其中(\mathbf{a} v = \lambda \mathbf{b} v) |
[V,D]=eigs(a,3) |
D,V = eigs(a, k=3) |
二维数组a 的前k=3 个最大特征值和特征向量 |
[Q,R]=qr(a,0) |
Q,R = linalg.qr(a) |
QR 分解 |
[L,U,P]=lu(a) ,其中 a==P'*L*U |
P,L,U = linalg.lu(a) ,其中 a == P@L@U |
带有部分主元选取的 LU 分解(注意:P(MATLAB)== transpose(P(NumPy))) |
conjgrad |
cg |
共轭梯度求解器 |
fft(a) |
np.fft.fft(a) |
数组 a 的傅里叶变换 |
ifft(a) |
np.fft.ifft(a) |
数组 a 的逆傅里叶变换 |
sort(a) |
np.sort(a) 或 a.sort(axis=0) |
对二维数组 a 的每一列进行排序 |
sort(a, 2) |
np.sort(a, axis=1) 或 a.sort(axis=1) |
对二维数组 a 的每一行进行排序 |
[b,I]=sortrows(a,1) |
I = np.argsort(a[:, 0]); b = a[I,:] |
将数组 a 按照第一列排序后保存为数组 b |
x = Z\y |
x = linalg.lstsq(Z, y) |
执行形如 (\mathbf{Zx}=\mathbf{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_
命令对子矩阵进行赋值。例如,对于二维数组 a
,可以执行:ind=[1, 3]; a[np.ix_(ind, ind)] += 100
。
HELP: Python 没有直接等价于 MATLAB 的 which
命令,但是 help
命令和 numpy.source
命令通常会列出函数所在的文件名。Python 还有一个 inspect
模块(使用 import inspect
导入),其中提供了一个 getfile
方法,该方法通常起作用。
INDEXING: MATLAB 使用基于 1 的索引,所以一个序列的初始元素索引为 1。Python 使用基于 0 的索引,所以一个序列的初始元素索引为 0。混淆和争议产生是因为每种方式都有优劣之处。基于 1 的索引与人们常用的自然语言使用方式一致,其中序列的“第一个”元素索引为 1。基于 0 的索引简化了索引操作。还可参考Edsger W. Dijkstra 教授的某篇文本。
RANGES:在 MATLAB 中,0:5
可以作为区间文字和“切片”索引使用(在圆括号内);然而,在 Python 中,形如 0:5
的结构只能作为“切片”索引使用(在方括号内)。因此,为了使 NumPy 具有类似简洁的区间构造机制,创建了有点古怪的 r_
对象。注意,r_
不像函数或构造函数一样调用,而是使用方括号进行索引,这允许在参数中使用 Python 的切片语法。
逻辑运算符:在 NumPy 中,&
或|
是按位 AND/OR 运算符,而在 MATLAB 中,&和|
是逻辑 AND/OR 运算符。这两者看起来可能是相同的,但存在重要的区别。如果你曾经使用过 MATLAB 的&
或|
运算符,你应该使用 NumPy 的 ufuncs logical_and
/logical_or
。MATLAB 的&
和|
运算符与 NumPy 的&
和|
运算符之间的显着差异包括:
- 非逻辑{0,1}输入:NumPy 的输出是输入的按位 AND 运算。MATLAB 将任何非零值视为 1,并返回逻辑 AND。例如,在 NumPy 中
(3 & 4)
是0
,而在 MATLAB 中3
和4
都被视为逻辑真,(3 & 4)
返回1
。 - 优先级:NumPy 的&运算符的优先级高于诸如
<
和>
的逻辑运算符;MATLAB 的优先级相反。
如果你知道你有布尔参数,你可以使用 NumPy 的按位运算符,但要小心处理括号,就像这样:z = (x > 1) & (x < 2)
。NumPy 没有logical_and
和logical_or
运算符形式是 Python 设计中不幸的结果。
重塑和线性索引:MATLAB 始终允许使用标量或线性索引来访问多维数组,NumPy 则不允许。线性索引在 MATLAB 程序中很常见,例如对矩阵进行find()
操作返回它们,而 NumPy 的find()
操作行为不同。在转换 MATLAB 代码时,可能需要首先将矩阵重塑为线性序列,进行一些索引操作,然后再重塑回去。由于重塑(通常)生成对存储空间的视图,因此应该可以相当有效地进行此操作。请注意,NumPy 中的 reshape 使用的扫描顺序默认为“C”顺序,而 MATLAB 使用 Fortran 顺序。如果你只是将其转换为线性序列并返回,这并不重要。但是,如果你要从依赖扫描顺序的 MATLAB 代码中转换重塑操作,那么此 MATLAB 代码:z = reshape(x,3,4);
应该在 NumPy 中变成z = x.reshape(3,4,order='F').copy()
。
‘array’或‘matrix’?我应该使用哪一个?
从历史角度来看,NumPy 提供了一个特殊的矩阵类型* np.matrix*,它是 ndarray 的子类,可以进行二进制运算和线性代数运算。你可能会在一些现有代码中看到它的使用,而不是* np.array*。那么,应该使用哪一个?
简短回答
使用数组。
- 支持在 MATLAB 中支持的多维数组代数
- 它们是 NumPy 的标准向量/矩阵/张量类型。许多 NumPy 函数返回数组而不是矩阵。
- 在元素级运算和线性代数运算之间存在明显区别。
- 你可以拥有标准向量或行/列向量。
直到 Python 3.5 之前,使用数组类型的唯一劣势是你必须使用dot
而不是*
来对两个张量(标量积,矩阵向量乘法等)进行乘法运算。自 Python 3.5 以来,你可以使用矩阵乘法@
运算符。
鉴于上述问题,我们打算最终弃用matrix
。
长回答
NumPy 包含array
类和matrix
类。array
类旨在为许多种数值计算提供通用的 n 维数组,而matrix
类旨在特定的线性代数计算。实际上,这两者之间只有少数几个关键的区别。
- 运算符
*
和@
,函数dot()
和multiply()
:
- 对于
array
,*
表示逐元素相乘,而**@
表示矩阵乘法**;它们有关联的函数multiply()
和dot()
。(在 Python 3.5 之前,@
不存在,必须使用dot()
进行矩阵乘法)。 - 对于
matrix
,*
表示矩阵乘法,对于逐元素相乘,必须使用multiply()
函数。
- 处理向量(一维数组)
- 对于
array
,形状为 1xN、Nx1 和 N 的向量是完全不同的。例如A[:,1]
返回形状为 N 的一维数组,而不是形状为 Nx1 的二维数组。一维array
的转置没有任何效果。 - 对于
matrix
,一维数组始终被上转换为 1xN 或 Nx1 矩阵(行向量或列向量)。A[:,1]
返回形状为 Nx1 的二维矩阵。
- 处理更高维度数组(ndim > 2)
array
对象可以有大于 2 的维度;matrix
对象始终具有确切的两个维度。
- 方便的属性
array
具有.T 属性,返回数据的转置。matrix
还具有.H、.I 和.A 属性,分别返回矩阵的共轭转置、逆矩阵和 asarray()。
- 方便的构造函数
array
构造函数以(嵌套)Python 序列作为初始化器。如,array([[1,2,3],[4,5,6]])
。matrix
构造函数另外接受方便的字符串初始化器。如matrix("[1 2 3; 4 5 6]")
。
使用两者都有利有弊:
array
:)
逐元素相乘很容易:A*B
。:(
必须记住,矩阵乘法有自己的操作符@
。:)
您可以将一维数组视为行向量或列向量。A @ v
将v
视为列向量,而v @ A
将v
视为行向量。这可以节省您的很多转置输入。:)
array
是“默认”的 NumPy 类型,因此经过最多测试,并且是第三方使用 NumPy 的代码最有可能返回的类型。:)
可以很好地处理任意维度的数据。:)
如果你熟悉张量代数,:
更接近语义。:)
所有操作(*
,/
,+
,-
等)都是逐元素的。:(
来自scipy.sparse
的稀疏矩阵与数组的交互性不佳。
matrix
:\\
行为更像 MATLAB 的矩阵。<:(
最多为二维。要保存三维数据,您需要array
或者可能是一个matrix
的 Python 列表。<:(
最少为二维。不能有向量。它们必须被强制转换为单列或单行矩阵。<:(
由于array
在 NumPy 中是默认值,一些函数可能返回一个array
,即使你给它们一个matrix
作为参数。这不应该发生在 NumPy 函数中(如果发生了,那是一个错误),但基于 NumPy 的第三方代码可能不会像 NumPy 那样遵守类型保留。:)
A*B
是矩阵乘法,因此看起来就像您在线性代数中编写一样(对于 Python >= 3.5,普通数组使用@
操作符具有相同的便利)。<:(
按元素相乘需要调用函数multiply(A,B)
。<:(
操作符重载的使用有点不合逻辑:*
不是按元素运行,但/
是。- 与
scipy.sparse
的交互方式更清晰。
因此,使用array
更加明智。的确,我们最终打算废弃matrix
。
自定义您的环境
在 MATLAB 中,用于自定义环境的主要工具是修改搜索路径,包含您喜欢函数的位置。您可以将这种定制放入 MATLAB 将在启动时运行的启动脚本中。
NumPy,或者更确切地说是 Python,具有类似的功能。
- 要修改 Python 搜索路径以包括您自己模块的位置,请定义
PYTHONPATH
环境变量。 - 要在启动交互式 Python 解释器时执行特定的脚本文件,请定义
PYTHONSTARTUP
环境变量,其中包含您启动脚本的名称。
与 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
链接
可以在mathesaurus.sf.net/
找到另一个有些过时的 MATLAB/NumPy 交叉参考。
可以在专题软件页面中找到用于科学工作的 Python 的工具的广泛列表。
请参阅Python 软件列表:脚本以获取使用 Python 作为脚本语言的软件列表
MATLAB®和 SimuLink®是 The MathWorks,Inc.的注册商标。
介绍
MATLAB®和 NumPy 有很多共同之处,但 NumPy 是为了与 Python 一起工作而创建的,并不是 MATLAB 的克隆。本指南将帮助 MATLAB 用户开始使用 NumPy。
一些关键区别
在 MATLAB 中,即使是标量的基本类型也是多维数组。MATLAB 中的数组赋值存储为双精度浮点数的 2D 数组,除非你指定维数和类型。对这些数组的 2D 实例的操作是基于线性代数中的矩阵运算的。 | 在 NumPy 中,基本类型是多维array 。NumPy 中的数组赋值通常存储为 n 维数组,以容纳序列中的对象所需的最小类型,除非你指定维数和类型。NumPy 执行逐个元素的操作,因此用* 乘以 2D 数组不是矩阵乘法 - 而是逐个元素的乘法。(自 Python 3.5 以来可用的@ 运算符可以用于传统的矩阵乘法。) |
MATLAB 从 1 开始编号索引;a(1) 是第一个元素。参见注释索引 |
NumPy,像 Python 一样,从 0 开始编号;a[0] 是第一个元素。 |
MATLAB 的脚本语言是为了线性代数而创建的,因此一些数组操作的语法比 NumPy 的更紧凑。另一方面,添加 GUI 和创建完整应用程序的 API 更多或多或少是事后想法。 | NumPy 基于 Python,这是一种通用语言。NumPy 的优势在于可以访问 Python 库,包括:SciPy,Matplotlib,Pandas,OpenCV等等。此外,Python 通常被嵌入为脚本语言到其他软件中,在那里也可以使用 NumPy。 |
MATLAB 数组切片使用传值语义,具有延迟写入复制的机制,以防在需要之前创建副本。切片操作会复制数组的部分。 | NumPy 数组切片使用传址,不会复制参数。切片操作是对数组的视图。 |
大致的等价物
下表列出了一些常见 MATLAB 表达式的大致等价物。这些是相似的表达式,而不是等价物。详情请参见文档。
在下表中,假设你已在 Python 中执行了以下命令:
import numpy as np from scipy import io, integrate, linalg, signal from scipy.sparse.linalg import cg, eigs
还假设下面的附注说明了“矩阵”,即参数为二维实体。
通用目的的等价物
MATLAB | NumPy | 注释 |
help func |
info(func) 或help(func) 或func? (在 IPython 中) |
获取函数func的帮助 |
which func |
参见注释帮助 | 查找func的定义位置 |
type func |
np.source(func) 或func?? (在 IPython 中) |
打印func的源代码(如果不是原生函数) |
% comment |
# comment |
用文本comment 注释代码行 |
|
for i=1:3 fprintf('%i\n',i) end
|
for i in range(1, 4): print(i)
使用 for 循环使用 range 打印数字 1、2 和 3 |
a && b |
a || b |
|
>> 4 == 4 ans = 1 >> 4 == 5 ans = 0
|
>>> 4 == 4 True >>> 4 == 5 False
Python 中的布尔对象是 True 和 False ,不同于 MATLAB 的逻辑类型为 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 并打印结果 |
1*i , 1*j , 1i , 1j |
eps |
load data.mat |
ode45 |
ode15s |
线性代数的等价操作
MATLAB | NumPy | 注释 |
ndims(a) |
np.ndim(a) 或 a.ndim |
数组 a 的维数 |
numel(a) |
np.size(a) 或 a.size |
数组 a 的元素个数 |
size(a) |
np.shape(a) 或 a.shape |
数组 a 的“大小” |
size(a,n) |
a.shape[n-1] |
获取数组 a 的第 n 维中的元素数。 (注意 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 构造一个矩阵 |
a(end) |
a[-1] |
访问 MATLAB 向量(1xn 或 nx1)或 1D NumPy 数组 a (长度为 n)中的最后一个元素 |
a(2,5) |
a[1, 4] |
访问 2D 数组 a 中第二行第五列的元素 |
a(2,:) |
a[1] 或 a[1, :] |
2D 数组 a 的整个第二行 |
a(1:5,:) |
a[0:5] 或 a[:5] 或 a[0:5, :] |
数组 a 的前 5 行 |
a(end-4:end,:) |
a[-5:] |
2D 数组 a 的最后 5 行 |
a(1:3,5:9) |
a[0:3, 4:9] |
2D 数组 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,:) 或 flipud(a) |
a[::-1,:] |
行以相反顺序的a |
a([1:end 1],:) |
a[np.r_[:len(a),0]] |
在末尾附加第一行后的a |
a.' |
a.transpose() 或 a.T |
a 的转置 |
a' |
a.conj().transpose() 或 a.conj().T |
a 的共轭转置 |
a * b |
a @ b |
矩阵相乘 |
a .* b |
a * b |
逐元素相乘 |
a./b |
a/b |
逐元素除法 |
a.³ |
a**3 |
逐元素指数运算 |
(a > 0.5) |
(a > 0.5) |
其 i,j 元素为(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]] |
提取向量 v 中大于 0.5 的列的a |
a(:,find(v>0.5)) |
a[:, v.T > 0.5] |
提取向量 v 中大于 0.5 的列的a |
a(a<0.5)=0 |
a[a < 0.5]=0 |
a 中小于 0.5 的元素归零 |
a .* (a>0.5) |
a * (a > 0.5) |
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') 。 |
1:10 |
np.arange(1., 11.) 或 np.r_[1.:11.] 或 np.r_[1:10:10j] |
创建一个递增向量(见注 RANGES) |
0:9 |
np.arange(10.) 或 np.r_[:10.] 或 np.r_[:9:10j] |
创建一个递增向量(见注 RANGES) |
[1:10]' |
np.arange(1.,11.)[:, np.newaxis] |
创建一个列向量 |
zeros(3,4) |
np.zeros((3, 4)) |
64 位浮点零值填充的 3x4 二维数组 |
zeros(3,4,5) |
np.zeros((3, 4, 5)) |
64 位浮点零值填充的 3x4x5 三维数组 |
ones(3,4) |
np.ones((3, 4)) |
64 位浮点 1 值填充的 3x4 二维数组 |
eye(3) |
np.eye(3) |
3x3 单位矩阵 |
diag(a) |
np.diag(a) |
返回 2D 数组a 的对角线元素的向量 |
diag(v,0) |
np.diag(v, 0) |
返回一个非零值为向量v 元素的方形对角矩阵 |
|
rng(42,'twister') rand(3,4)
|
from numpy.random import default_rng rng = default_rng(42) rng.random(3, 4)
or older version: random.rand((3, 4))
| 用默认的随机数生成器和种子 = 42 生成一个随机的 3x4 数组 |
linspace(1,3,4) |
np.linspace(1,3,4) |
在 1 和 3 之间等间隔取 4 个样本,包括 1 和 3 |
[x,y]=meshgrid(0:8,0:5) |
np.mgrid[0:9.,0:6.] 或 np.meshgrid(r_[0:9.],r_[0:6.]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
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]) |
两个二维数组:一个是 x 值,另一个是 y 值 |
np.ix_([1,2,4],[2,4,5]) |
在网格上评估函数的最佳方法 | |
repmat(a, m, n) |
np.tile(a, (m, n)) |
创建 a 的 m 行 n 列的副本 |
[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)) 或 np.vstack((a,b)) 或 np.r_[a,b] |
拼接 a 和 b 的行 |
max(max(a)) |
a.max() 或 np.nanmax(a) |
a 的最大元素(对于 MATLAB 的 ndims(a)<=2,如果存在 NaN,则 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) 或 np.linalg.norm(v) |
向量 v 的 L2 范数 |
a & b |
logical_and(a,b) |
逐元素 AND 运算符(NumPy ufunc)参见注释 LOGICOPS |
a | b |
np.logical_or(a,b) |
逐元素 OR 运算符(NumPy ufunc)参见注释 LOGICOPS |
bitand(a,b) |
a & b |
按位 AND 运算符(Python 原生和 NumPy ufunc) |
bitor(a,b) |
a | b |
按位 OR 运���符(Python 原生和 NumPy ufunc) |
inv(a) |
linalg.inv(a) |
方阵 a 的逆 |
pinv(a) |
linalg.pinv(a) |
二维数组 a 的伪逆 |
rank(a) |
np.linalg.matrix_rank(a) |
二维数组 a 的秩 |
a\b |
如果 a 是方阵,则为 linalg.solve(a, b) ;否则为 linalg.lstsq(a, b) |
解方程 a x = b 的解 x |
b/a |
解方程 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 的奇异值分解 |
chol(a) |
linalg.cholesky(a) |
二维数组 a 的 Cholesky 分解 |
[V,D]=eig(a) |
D,V = linalg.eig(a) |
a 的特征值 (\lambda) 和特征向量 (v) ,满足 (\mathbf{a} v = \lambda v) |
[V,D]=eig(a,b) |
D,V = linalg.eig(a, b) |
a ,b 的特征值 (\lambda) 和特征向量 (v) ,满足 (\mathbf{a} v = \lambda \mathbf{b} v) |
[V,D]=eigs(a,3) |
D,V = eigs(a, k=3) |
找到二维数组 a 中最大的 k=3 个特征值和特征向量 |
[Q,R]=qr(a,0) |
Q,R = linalg.qr(a) |
QR 分解 |
[L,U,P]=lu(a) ,其中 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.fft(a) |
a 的傅里叶变换 |
ifft(a) |
np.fft.ifft(a) |
a 的傅立叶反变换 |
sort(a) |
np.sort(a) 或a.sort(axis=0) |
排序 2D 数组a 的每一列 |
sort(a, 2) |
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) |
执行形式为(\mathbf{Zx}=\mathbf{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 或更高维数组 |
NumPy 1.26 中文官方指南(三)(2)https://developer.aliyun.com/article/1510616