2017-05-30 218 views
2

矩陣A是我的起始矩陣,它包含從SD卡上的MPU6050和GPS記錄的數據(經度,緯度,時間,斧,Ay,Az,Gx,Gy,Gz)。從矩陣A中提取所有行的更好方法,該矩陣包含矩陣B的一個元素

我計算了窗口大小爲5的Az的標準偏差,並確定了滿足條件(>閾值)的所有元素。

然後在矩陣「large_windows」我存儲窗口中滿足條件的所有Az的索引。

從矩陣「large_windows」我計算新的矩陣B與所有從矩陣A包含矩陣的行「large_windows」元件。

我覺得我的代碼是effective,但非常醜陋和混亂,加上我仍然不是很實用與indexing,但我想了解它。


1.是否有更好的解決方案?


2.可以使用一個邏輯索引?怎麼樣?它是有效的*?

這裏我的代碼,是一個簡單的例子,與一般條件,瞭解整個概念更好的不僅是我的具體情況, starting from suggestions of a previous problem(how to create a sliding window

%random matix nXm 
a=rand(100,6); 

%window dimension 
window_size=4; 

%overlap between two windows 
overlap=1; 

%increment needed 
step=window_size - overlap; 

%std threshold 
threshold=0.3; 
std_vals= NaN(size(a,1),1); 

%The sliding window will analyze only the 5th column 
for i=1: step: (size(a,1)-window_size) 
    std_vals(i)=std(a(i:(i+window_size-1),5)); 
end 

% finding the rows with standard deviation larger than threshold 
large_indexes = find(std_vals>threshold); 

%Storing all the elements that are inside the window with std>threshold 

large_windows = zeros(numel(large_indexes), window_size); 
for i=1:window_size 
    large_windows(:,i) = large_indexes + i - 1; 
end 

% Starting extracting all the rows with the 5th column outlier elements 
n=numel(large_windows); 

%Since i will work can't know how long will be my dataset 
%i need to knwo how is the "index distance" between two adjacent elements 
% in the same row [es. a(1,1) and a(1,2)] 


diff1=sub2ind(size(a),1,1); 
diff2=sub2ind(size(a),1,2); 

l_2_a_r_e = diff2-diff1 %length two adjacent row elements 
large_windows=large_windows' 
%calculating al the index of the element of a ith row containing an anomaly 
for i=1:n 

    B{i}=[a(large_windows(i))-l_2_a_r_e*4 a(large_windows(i))-l_2_a_r_e*3 a(large_windows(i))-l_2_a_r_e*2 a(large_windows(i))-l_2_a_r_e*1 a(large_windows(i))-l_2_a_r_e*0 a(large_windows(i))+l_2_a_r_e]; 
end 

C= cell2mat(B'); 

我還發布之前讀了一些問題,但This was to specific

B的不包括在所以這個問題是不是在THI有益Find complement of a data frame (anti - join)

I don't know how to useismember的具體情況

我希望我的畫能更好地解釋我的問題:)

感謝您的時間 enter image description here

+0

我不知道我是否正確理解你在找什麼。例如,您可以使用'large_windows = repmat(large_indexes。',window_size,1)+(0:3)。'或'large_windows = bsxfun(@ plus,large_indexes,0:3)來代替for循環。 '創建你的'large_windows'數組。這可能會更有效一些。你在找這種東西嗎?你的目標是讓你的代碼更快嗎?你在處理大量的數據嗎?或者你只是試圖預先驗證代碼並理解一些花哨的matlab索引的東西? – Max

+0

@uomodellamansarda如果最終結果是矩陣B,那麼您並不需要計算矩陣「large_windows」。您可以直接從「large_indexes」獲得「B」。 您對此有何看法? –

+0

@Max我的目標是讓我的代碼更快,因爲我有超過4k行,但我想了解一些花哨的matlab索引的東西(他們沒有用嗎?我是noob,沒有計算機科學背景,每個人都讓我感到沮喪在MATLAB上使用for-loop):)感謝您的建議,我將學習,然後嘗試它:) <3 –

回答

1

這裏有一個新的方法來實現你真正想要達到的效果。我糾正了你所犯的兩個錯誤,並用bsxfun替換了所有for循環,這是一個非常有效的功能來完成這樣的事情。對於Matlab R2016b或更新版本,您也可以使用implicit expansion而不是bsxfun
我開始執行滑動窗口。代替您的for環回,您可以使用

stdInds=bsxfun(@plus,1:step:(size(a,1)-overlap),(0:3).'); 
std_vals=std(a(sub2ind(size(a),stdInds,repmat(5,size(stdInds))))); 

這裏。 bsxfun創建一個數組來保存你的窗口的行。它在每一列中都有1個窗口。這些行需要轉換爲數組的線性索引,以便獲得一個值數組,並將其傳遞給std函數。在你的實現中,你在這裏犯了一個小錯誤,因爲你的for -loop結尾爲size(a,1)-window_size,實際上應該以size(a,1)-overlap結束,否則你錯過了最後一個窗口。
現在,我們得到了我們可以檢查哪些比預定義的門限更大然後變換它們放回相應行窗口的STD值:

highStdWindows=find(std_vals_2>threshold); 
highStdRows=bsxfun(@plus,highStdWindows*step-step+1,(0:3).'); 

highStdWindows包含Windows的索引,即具有高標準值。在下一行中,我們使用highStdWindows*step-step+1來計算這些窗口的起始行,然後我們再次使用bsxfun來計算與每個窗口對應的其他行。
現在我們來看看代碼中的實際錯誤。這條線就在這裏

B{i}=[a(large_windows(i))-l_2_a_r_e*4 a(large_windows(i))-l_2_a_r_e*3 a(large_windows(i))-l_2_a_r_e*2 a(large_windows(i))-l_2_a_r_e*1 a(large_windows(i))-l_2_a_r_e*0 a(large_windows(i))+l_2_a_r_e]; 

沒有做你想做的事。不幸的是,你在這裏錯過了幾個括號。通過這種方法,您可以獲取矩陣a的large_windows(i)'元素,並從中減去4*l_2_a_r_e。你想寫是

B{i}==[a(large_windows(i)-l_2_a_r_e*4) % and so on 

這種方式,你會從你傳遞給a索引的。減去4*l_2_a_r_e。這仍然是錯誤的,因爲在large_windows中存儲了行號而不是對應於矩陣a的線性索引。
不過這可以使用,而不是線性的索引下標索引來實現輕鬆了不少:

rowList=reshape(highStdRows,1,[]); 
C=a(rowList,:); % all columns (:) and from the rows in rowList 

這兩個簡單的線條告訴MATLAB把存儲在highStdRows與所有列(由:表示)中的所有行。有了這個,如果有兩個相鄰的窗口的高標準值,你會得到重疊的行兩次。如果你想獲得索引在Matlab中如何工作來看看LuisMendo的post有關此主題的進一步內部

rowList=unique(reshape(highStdRows,1,[])); 
C=a(rowList,:); 

:如果你不希望出現這種情況,你可以使用此代碼來代替。

+0

謝謝,我明白了我所有的錯誤!現在我試圖理解這一點:'highStdWindows * step-step + 1'清楚'bsxfun'是如何工作的,不清楚爲什麼你應該乘以'* step'然後減去'-step + 1' :)我試過在MATLAB上的代碼,看看結果,但我在這一點上陷入困​​境。在此先感謝 –

+0

在'highStdWindows'中,我們存儲具有高標準值的窗口號。所以現在我們需要計算相應的行數。想象一下,我們只適用於大小爲4的窗口,並且有重疊窗口,第一,第三和第四窗口具有較高的標準值。現在'highStdWindows'將包含數組''[1,3,4]',但我們需要計算這些窗口以這些窗口開始的行。把這個矢量和'step'相乘並且加上'-step + 1'確實是這樣的。例如窗口3由'[7 8 9 10]'組成,我們用'3 * step-step + 1 = 7'來計算開始行,其他的用'bsxfun' – Max

+0

我現在希望它更清楚 – Max