Matlab
与Numpy操作的差异 – Numpy for Matlab User
1、Numpy和Matlab的差异
1.1 关键的不同
Matlab | Numpy |
---|---|
Matlab中即使是标量也是多维数组。数组的类型默认为二维的双精度浮点型。除非特别指定数组的数据类型。二维数组的操作类似于线性代数中矩阵的操作 | Numpy中的基本数据类型是多维数组。Numpy中通常是n维数组,会按照顺序保存。Numpy的操作是按照元素到元素,因此二维数组的*并不表示矩阵乘法,而是元素乘法。@表示矩阵乘法。 |
matlab的下标是从1开始的。 | Numpy的下标是从0开始的。Python |
Matlab的脚本语言更像线性代数,因此数组操作的语法相比于Numpy更加紧凑。同时Matlab有GUI的API,降低了代码的完整性。 | Numpy是基于Python的,更加通用。同时Numpy和深度学习的Pytorch的兼容性也比较好。Numpy可以和Python的其他包一起操作。Python经常和其他语言联合使用,Numpy也是可用的。 |
Matlab数组切片使用按值传递,采用延迟写入来防止产生副本。切片操作只复制数组的一部分。 | Numpy切片使用的是索引,并不会复制。切片操作书堆数组的部分可视化。 |
1.2 基本操作对比
Matlab | Numpy | Note |
---|---|---|
help func | info(func) or help(func) | 获得函数的详细信息 |
which func | see note help | 找到函数被定义的位置 |
type func | np.source(func) | 如果不是内置函数访问函数的源 |
% 注释 | # 注释 | 给代码添加注释 |
a && b | a and b | 与操作 |
`a | b` | |
1(True) 、0(False) | True / False | 逻辑操作 |
if -- elseif -- end | if -- elif | if – else条件分支操作 |
load data.mat | io.loadmat(data.mat) | 加载mat格式数据 |
1.3 线性代数操作
Matlab | Numpy | Note |
---|---|---|
ndims(a) | np.ndim(a) or a.ndim | 数组维度 |
numel(a) | np.size(a) or a.size | 数组元素个数 |
size(a) | np.shape(a) or a.shape | 数组形状(matlab返回的是行和列的元素,numpy返回的是元组,需要用两个参数接收行列数才能返回元素,想当于是元组拆包) |
size(a, n) | a.shape[n - 1] | 得到第0维的元素数。因为matlab从1开始,python从0开始,所以np中的n需要减去1 |
[1 2 3; 4 5 6] | np.array([1., 2., 3.], [4., 5., 6.]) | 表示 2 * 3 2D的数组 |
[a b; c d] | np.block([[a b], [c, d]]) | 通过块a, b, c, d来创建数组 |
a(end) | a[-1] | 访问数组的最后一个元素 |
a(2, 5) | a[1, 4] | 访问数组中第2行5列的元素 |
a(2, :) | a[1] or a[1, :] | 访问数组第2行之后的全部数据 |
a(1:5, :) | a[0:5] or a[0:5, :] or a[ :5] | 访问前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[np.ix_([1, 3, 4], [0, 2]) | 访问2 45行的1,3列数据 |
a(3:2:21, :) | a[2:21:2] | 从第3行到21行,隔一行取一次 |
a(1:2:end, :) | a[::2, :] | 从第1行到end,隔一行取一次值 |
a(end:-1:1,:) or flipud(a) | a[::-1, :] | 数组逆序输出 |
a([1:end 1], :) | a[np.r_[:len(a), 0]] | 复制第一行添加到数组最后 |
a.' | a.transpose() or a.T | 转置数组a |
a' | a.conj().transpose() or a.conj().T | 共轭转置a |
a * b | a @ b | 矩阵相乘 |
a .* b | a * b | 按元素相乘 |
a ./ b | a / b | 按元素相除 |
a .^ 3 | a ** 3 | 按元素求幂 |
(a > 0.5) | (a > 0.5) | 元素值和0.5比较大小。matlab返回的是逻辑值0 or 1, Numpy返回的是True or False |
find(a > 0.5) | np.nonzero(a > 0.5) | 找到大于0.5的元素对应的索引,matlab返回的是值,Numpy返回的是索引;如果要返回值,Numpy的表示方式为a[np.nonzeros(a > 0.5)] |
a(:, find( v > 0.5)) | a[: , np.nonzero( v > 0.5)[0]] | 提取列中向量 v > 0.5 的元素 |
a(a < 0.5) = 0 | a[a < 0.5] = 0 | 将a中小于0.5的元素赋值为0 |
a .* a(a > 0.5) | a * (a > 0.5) | 先取出a中大于5的元素,在和a矩阵按元素相乘 |
a(:) = 3 | a[:] = 3 | 将a中的元素全部赋值为3 |
y = x | y = x.copy() | 浅拷贝,共享内存地址 |
y = x(2, :) | y = x[1, :].copy() | Numpy通过引用切片 |
y = x(:) | y = x.flatten() | 将数组展平成一列 |
zeros(3, 4) | np.zeros((3, 4) | 创建3 * 4的全零数组 |
zeros(3, 4, 5) | np.zeros((3, 4, 5)) | 创建3 * 4 * 5的3D的全零数组 |
ones(3, 4) | np.ones((3, 4)) | 创建2D的全1数组 |
eye(3) | np.eye(3) | 创建3 * 3的单位矩阵 |
diag(a) | np.diag | 返回矩阵对角线上的元素 |
rng(42, 'twister') rand(3, 4) | from numpy.random import default_rng rng = default_rng(42) rng.random(3, 4) | 默认随机产生3 * 4的数组,定义种子是便于看到重复的结果 |
x, y = meshgrid(0:8, 0:5) | np.mgrid[0:9.,0:6.]or np.meshgrid(r_[0:9.],r_[0:6.]) | 产生2D数组,一个是X,另外一个是y |
repmat(a, m, n) | np.tile(a, (m, n)) | 通过a的n个副本创建m |
[a b] | np.concatenate((a, b), 1), np.hstack((a, b)) | 将数组按列拼接 |
[a; b] | np.concatenate((a, b)), np.vstack((a, b)) | 将数组按行拼接 |
max(max(a)) | a.max() | 返回数组中值最大的元素 |
max(a) | a.max(0) | 按列取出最大值 |
max(a, [], 2) | a.max(1) | 按行取出最大值 |
max(a, b) | np.maximum(a, b) | 按元素比较a, b两个矩阵的值, 返回每对中的最大值。本质上相当于取两个矩阵中的最大值 |
a & b | logical_and(a, b) | 逻辑与运算 |
a | b | np.logical_or(a, b) | 逻辑或运算 |
inv(a) | linalg.inv(a) | 矩阵的逆 |
sort(a) | np.sort(a) | 按列排序 |
sort(a, 2) | a.sort(axis = 1) | 按行排序元素 |
unique(a) | np.unique(a) | 求矩阵中的唯一值 |
squeeze(a) | a.squeeze() | 删除数组a的单一维度,matlab返回的是2D或者更高维,Numpy返回的是0D或者更高维 |
注:
- 转置和共轭转置的区别,矩阵分为实数矩阵和复数矩阵。因此对于实数而言,转置矩阵和共轭转置得到的是同一值。但是对于复数矩阵需要先做转置再取共轭。
- 区分矩阵乘法和元素相乘的差别。矩阵乘法需要满足矩阵乘法的要求;按元素相乘需要满足矩阵大小一致
- 创建全零矩阵或者全1矩阵时,numpy的输入必须为元组,类似于pytorch中对张量的创建
1.4 特别说明
- 子矩阵:Numpy中可以传入索引的列表,通过
ix_
命令,例如:
ind = [1, 3], a[np.ix_(ind, ind)] += 100
- Help选项:Python中没有which,但是
help
和numpy.source
会列出文件名以及函数的位置 - indexing:Matlab中的索引从1开始,而python是从0开始的。
- range:Matlab中0:5表示的是范围也是数组索引的切片,而在Python中只能表示切片的索引。在表示范围时Matlab的范围都可以取得到,Python的范围是前闭后开的。范围表示的最后一个值是取不到的。
示例:
Python:
for i in range(5):
print(i)
>>> 0
1
2
3
4
Matlab:
for j = 0:5
disp(i)
end
>>> 0
1
2
3
4
5
- reshape 和 linear indeing:MATLAB 始终允许使用标量或线性索引访问多维数组,而 NumPy 则不允许。线性索引在 MATLAB 程序中很常见,例如矩阵上的 find() 返回它们,而 NumPy 的 find 返回结果则不同。