我正致力于将代码从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。任何人都可以让我知道我在哪里做错了吗?
答案 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