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,但是helpnumpy.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 返回结果则不同。