最近在看一个算法的matlab代码,想自己用Python实现,中间遇到了一些matlab和numpy的转换问题,特别记录一下,当然,这些都只是我目前遇到的,肯定是不完整版。
matlab和numpy对应表
matlab | numpy | 说明 |
---|---|---|
size(a) | a.shape or np.shape(a) | |
size(a,n) | a.shape[n-1] | matlab中矩阵行列从1开始计,numpy中从0开始计 |
ones(n,m) | np.ones((n, m)) | 注意是两层括号 |
zeros(n,m) | np.zeros((n,m)) | 同上 |
eye(n) | eye(n) | 单位矩阵 |
a*b | a.dot(b) or np.dot(a,b) | a,b均为矩阵,a的列数等于b的行数 |
5*a | 5*a | |
a.*b | a*b | |
a’*a | np.dot(a.conj().T, a) | a为矩阵 |
a/b | ||
a./b | a/b | |
a\b | linalg.solve(a,b) or linalg.lstsq(a,b) | a是方阵的时候使用前者,其他情况使用后者 |
a.’ | a.transpose() or a.T | 转置 |
a’ | a.conj().transpose() or a.conj().T | |
a.^2 | a**2 | |
norm(a) | sqrt(dot(a,a)) or np.linalg.norm(a) | 默认是L2 |
a&&b | a and b | |
a||b | a or b | |
sort(a) | np.sort(a) or a.sort() | |
sqrt(a) | np.sqrt(a) | |
diag(a) | np.diag(np.diag(a)) | a是一个矩阵 |
a(end) | a[-1] | |
[v1 v2 v3] | np.c_[v1,v2,v3] or np.hstack((v1,v2,v3)) | 连接行 |
[v1;v2;v3] | np.r_[v1,v2,v3] or np.vstack((v1,v2,v3)) | 连接列 |
max() | max() | |
max(a,b) | maximum(a,b) | 比较两个数组的每个位置,由每个位置的最大值组成新数组返回 |
abs() | abs() | |
sum() | sum() | |
eps | np.spacing(1) | |
inf | np.inf | 无穷大 |
disp() or fprintf() | print() | 输出 |
a(2,:) | a[1] or a[1,:] | 取矩阵的第二行,这种对矩阵行列的操作,一般只需要把()改成[],然后索引-1 |
其他一些问题
在matlab中有一个求对角矩阵的函数:diag(a),a为矩阵,得到的结果是以矩阵a为对角线,其余元素为0的一个新的矩阵,和矩阵的大小大小相同。
而numpy的diag(a)的功能完全不一样,具体如下:
import numpy as np
a = np.arange(1, 4)
b = np.arange(1, 10).reshape(3, 3)
print(a)
print(np.diag(a))
print(b)
print(np.diag(b))
[1 2 3]
[[1 0 0]
[0 2 0]
[0 0 3]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[1 5 9]
我们可以看出来当np.diag(a)中的a是一维数组的时候,结果会返回一个以一维数组为对角线元素的矩阵,当a是一个二维数组时,结果会返回数组的对角线元素。所以很多人提到可以使用两个diag()函数,即np.diag(np.diag())来完成matlab中的diag(),但我当时并未想到,故使用了以下方法来实现。
n = np.size(a, axis=1)
a = np.diag(a) * np.eye(n)
待解决问题
在改写中还遇到一个比较麻烦的地方。
[p,ntask] = size(beta);
for i = 1:p
d(i) = 0.5 ./ (sum(beta(i,:).^2)+eps);
end
上面是matlab的代码,下面是使用numpy的python代码
p = np.size(beta, 0)
d = np.empty(shape=(1, 0))
for i in range(p):
dt = 0.5 / (sum(beta[i, :] ** 2) + np.spacing(1))
d = np.append(d, [[dt]], axis=1)
这个地方之后再详细写,还有matlab中传参个数可以不固定,然后利用nargin来判断参数个数的问题,以及matlab中可以使用以下的方式定义和调用。
para.lambda.u1 = 0.01;
para.lambda.v1 = 0.01;
[u, v] = train(train_set, para);
在train中直接使用lambda.u1
调用
这样的写法还没有找到类似的写法,等以后再来解决。