2017-05-30 219 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