2017-06-20 44 views
6

我在Matlab下面的代碼,我不熟悉:如何將矩陣從Matlab轉換爲Python?

function segments = segmentEnergy(data, th) 
    mag = sqrt(sum(data(:, 1:3) .^ 2, 2)); 
    mag = mag - mean(mag); 

    above = find(mag>=th*std(mag)); 
    indicator = zeros(size(mag)); 
    indicator(above) = 1; 
    plot(mag); hold on; plot(indicator*1000, 'r') 
end 

我寫在Python這下面的函數:

def segment_energy(data, th): 
    mag = np.linalg.norm((data['x'], data['y'], data['z'])) 
    print "This is the mag: " + str(mag) 
    mag -= np.mean(mag) 

    above = np.where(mag >= th * np.std(mag)) 
    indicator = np.zeros(mag.shape) 
    indicator[above] = 1 
    plt.plot(mag) 
    plt.plot(indicator * 1000, 'r') 
    plt.show() 

我得到一個錯誤:

line 23, in segment_energy 
indicator[above] = 1 
IndexError: too many indices for array 

data是從包含三軸加速度計數據的CSV文件讀取的一個熊貓DataFrame。加速度計數據的軸是x,yz。數據幀的列爲timestamp,time skipped,x,y,zlabel

錯誤是因爲Python代碼中的mag是一個標量,我把它當作一個矩陣對待它。但是,我不確定他們是如何將mag轉換爲MATLAB函數中的矩陣。

+2

什麼是數據? –

+0

'data'是來自CSV文件的數據幀。 – dirtysocks45

+0

然後嘗試使用'mag = np.linalg.norm(data.iloc [:,1:3] .values())' –

回答

3

默認情況下,numpy.linalg.norm的輸出將爲您提供單個標量值,給出您當前如何調用該函數。由於mag輸出現在是一個標量,代碼的其餘部分將無法實現預期的功能,原因如下:

  1. 執行平均減法單個標會給你一個0值(即mag <- mag - np.mean(mag) --> 0) 。

  2. above語句將始終返回單個元素的元組。該元素包含長度爲1的包含索引0的NumPy數組,表示在此情況下作爲標量的「數組」的第一個元素滿足約束條件。這總是令人滿意,因爲通過使用np.std的默認定義,單個常量的標準偏差也是0。

  3. 對單個標量值調用shape未定義,它實際上會給你一個空的形狀:()。請注意,如果您沒有減去numpy.mean,那麼執行mag.shape實際上會給您一個錯誤,因爲它不是NumPy數組。用np.mean減去標量到NumPy數組。

    觀察:

    In [56]: mag = 10 
    
    In [57]: type(mag) 
    Out[57]: int 
    
    In [58]: mag -= np.mean(mag) 
    
    In [59]: type(mag) 
    Out[59]: numpy.float64 
    
  4. 最後,調用indicator創建代碼會產生空維數組,因爲你正試圖索引到一個沒有大小的數組,它會給你一個錯誤。

觀察這個重複性的錯誤假設mag計算爲一定的價值...說... 10和th = 1

In [60]: mag = 10 

In [61]: mag -= np.mean(mag) 

In [62]: mag.shape 
Out[62]:() 

In [63]: th = 1 

In [64]: above = np.where(mag >= th * np.std(mag)) 

In [65]: indicator = np.zeros(mag.shape) 

In [66]: indicator 
Out[66]: array(0.0) 

In [67]: mag 
Out[67]: 0.0 

In [68]: indicator[above] = 1 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-67-adf9cff7610a> in <module>() 
----> 1 indicator[above] = 1 

IndexError: too many indices for array 

因此,你的解決方案是重新考慮你如何寫這個函數。MATLAB代碼假設data已經是二維矩陣了,所以它們將獨立計算每行的標準或長度。因爲我們現在知道輸入是一個熊貓DataFrame,所以我們可以很容易地在它上面應用numpy操作,就像在MATLAB中所做的一樣。假設您的代碼中的列標記爲xyz,並且每列都是numpy值的數組,則只需更改第一行代碼即可。

def segment_energy(data, th): 
    mag = np.sqrt(np.sum(data.loc[:, ['x','y','z']]** 2.0, axis=1)) # Change 
    mag = np.array(mag) # Convert to NumPy array 
    mag -= np.mean(mag) 

    above = np.where(mag >= th * np.std(mag)) 
    indicator = np.zeros(mag.shape) 
    indicator[above] = 1 
    plt.plot(mag) 
    plt.plot(indicator * 1000, 'r') 
    plt.show() 

代碼中的第一個語句是MATLAB中代碼的實際NumPy轉換。我們使用屬於熊貓DataFrameloc方法來索引您要查找的三列。我們還需要轉換爲NumPy數組,以便其餘的計算工作。

您也可以使用numpy.linalg.norm,但指定要操作。由於數據是2D的,指定axis=1來計算你的矩陣的逐行規範:

mag = np.linalg.norm(data.loc[:, ['x', 'y', 'z']], axis=1) 

以上將數據合併到一個數組NumPy的給你。

+0

'data'是從包含三軸加速計數據的CSV文件中讀取的熊貓數據框。加速度計數據的軸是'x','y'和'z'。謝謝你的幫助。如果您需要更多說明,請隨時詢問。數據幀的列按順序是'時間戳','跳過時間','x','y','z'和'標籤'。 – dirtysocks45

+1

@ dirtysocks45明白了。我編輯了我的答案,以利用您使用熊貓的事實。我已經使代碼不知道列的位置,並直接使用標籤。 – rayryeng

+1

最終解決了問題。謝謝。 – dirtysocks45