2014-01-18 72 views
1

我正在將代碼從matlab轉換爲python。將代碼從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×4,但我得到4×3在python。任何人都可以讓我知道我在做什麼錯誤嗎?

+0

您正在使用什麼版本的numpy的嗎? –

回答

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]]) 

計算通過在numpy.linalg.norm使用參數axis=0平方根的列的準則。

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),所以我們可以使用通過廣播中的相應值在scale劃分的q每一列。

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 
+0

如何做len = sum(sqrt(sum(v。* v)))/ N;與numpy 1.8? – sam

+1

Matlab表達式sqrt(sum(v。* v))給出'v'列的歐幾里得範數,所以它可以用numpy表示爲'np.linalg.norm(v,axis = 0)' 。然後'len_ = np.linalg.norm(v,axis = 0).sum()/ N'。如果'N'是'v'的列數,那麼加法和除以'N'就是平均值,所以'len_ = np.linalg.norm(v,axis = 0).mean()'。 –