将代码从matlab转换为python时的尺寸错误

时间:2014-01-18 07:46:51

标签: python matlab numpy

我正致力于将代码从matlab转换为python。

表示值,

N = 100
V = [[ -7.94627203e+01  -1.81562235e+02  -3.05418070e+02  -2.38451033e+02][  9.43740653e+01   1.69312771e+02   1.68545575e+01  -1.44450299e+02][  5.61599000e+00   8.76135909e+01   1.18959245e+02  -1.44049237e+02]]

V是numpy数组。

for i = 1:N
    L(i) = sqrt(norm(v(:,i)));
    if L(i) > 0.0001
        q(:,i) = v(:,i)/L(i);
    else
        q(:,i) = v(:,i)*0.0001;
    end
end

我已将此代码转换为:

L = []
q = []


for i in range(1, (N +1)):
    L.insert((i -1),np.sqrt( np.linalg.norm(v[:, (i -1)])))
    if L[(i -1)] > 0.0001:
        q.insert((i -1), (v[:, (i -1)] / L[(i -1)]).tolist())
    else:
        q.insert((i -1), (v[:, (i -1)] * 0.0001).tolist())
q = np.array(q)
return q, len_

但是,在matlab中,结果尺寸是3 x 4但我在python中得到4 x 3。任何人都可以让我知道我在哪里做错了吗?

1 个答案:

答案 0 :(得分:1)

您要将长度为3的列表插入q。完成创建q的循环后,q是一个包含4个项目的列表,其中每个项目都是长度为3的列表。因此np.array(q)创建一个形状为4x3的数组。您可以将倒数第二行更改为:

q = np.array(q).T

或者,您可以更有效地使用numpy来消除所有显式for循环。例如,如果您使用numpy 1.8,则norm函数接受axis参数。

这是代码的矢量化版本。

首先,本例的一些设置。

In [152]: np.set_printoptions(precision=3)

In [153]: np.random.seed(111)

创建一些可以使用的数据。

In [154]: v = 5e-9 * np.random.randint(0, 3, size=(3, 4))

In [155]: v
Out[155]: 
array([[  0.000e+00,   0.000e+00,   0.000e+00,   0.000e+00],
       [  1.000e-08,   5.000e-09,   1.000e-08,   1.000e-08],
       [  1.000e-08,   0.000e+00,   5.000e-09,   0.000e+00]])

使用axis=0中的参数numpy.linalg.norm计算列规范的平方根。

In [156]: L = np.sqrt(np.linalg.norm(v, axis=0))

In [157]: L
Out[157]: array([  1.189e-04,   7.071e-05,   1.057e-04,   1.000e-04])

使用numpy.where选择要将v的列划分为创建q的值。

In [158]: scale = np.where(L > 0.0001, L, 1000.0)

In [159]: scale
Out[159]: array([  1.189e-04,   1.000e+03,   1.057e-04,   1.000e+03])

q具有形状(3,4),scale具有形状(4,),因此我们可以使用广播将q的每一列除以相应的值scale

In [160]: q = v / scale

In [161]: q
Out[161]: 
array([[  0.000e+00,   0.000e+00,   0.000e+00,   0.000e+00],
       [  8.409e-05,   5.000e-12,   9.457e-05,   1.000e-11],
       [  8.409e-05,   0.000e+00,   4.729e-05,   0.000e+00]])

这里重复的是矢量化代码的三行:

L = np.sqrt(np.linalg.norm(v, axis=0))
scale = np.where(L > 0.0001, L, 1000.0)
q = v / scale