从矩阵A提取包含矩阵B元素的所有行的更好方法 [英] Better way to extract all the rows from a Matrix A that contain an element of a matrix B

查看:123
本文介绍了从矩阵A提取包含矩阵B元素的所有行的更好方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

矩阵A是我的起始矩阵,它将从MPU6050和GPS记录的数据保存在SD卡上(纬度,经度,时间,Ax,Ay,Az,Gx,Gy,Gz).

Matrix A is my starting matrix it holds the data logged from my MPU6050 and GPS on an SD Card (Latitude, Longitude, Time, Ax, Ay, Az, Gx,Gy,Gz).

我计算了窗口大小为5时Az的标准偏差,并确定了所有满足条件(>阈值)的元素.

I calculated the standard deviation of Az for window size of 5 and identified all the elements that satisfy a condition (>threshold).

然后在矩阵大窗口" 中,我将满足条件的所有Az的索引存储在窗口中.

Then in a matrix "large_windows" i stored the index of all the Az in the window that satisfy the condition.

根据矩阵大窗口" ,我使用矩阵A中包含矩阵大窗口" 元素的所有行,计算了一个新的矩阵B.

From matrix "large_windows" i calculated a new matrix B with all the rows from matrix A that contain the matrix "large_windows" elements.

我认为我的代码有效,但是非常丑陋且混乱,再加上 索引 ,但我想学习.

I think my code is effective, but very ugly and chaotic, plus i am still not very practical with indexing but i want to learn it.

1.是否存在更好的解决方案?

2.可以使用逻辑索引吗?如何?这是有效的*吗?

这是我的代码,是具有通用条件的简化示例,不仅可以了解我的具体情况,还可以更好地理解整个概念,

Here my code, is a simplified example, with generic condition, to understand the whole concept better not only my specific situation, 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');

在发布问题之前,我还阅读了一些问题,但

I also read some question before posting it, but This was to specific

B未包含在A中,因此此问题无济于事查找数据框的补数(反联接)

B is not included in A so this question is not helpful Find complement of a data frame (anti - join)

我不知道如何使用 ismember在这种情况下

我希望我的图纸能更好地解释我的问题:)

I hope my drawing could better explain my problem :)

谢谢您的时间

推荐答案

这是一种实现您实际想要实现的结果的新方法.我更正了您犯的2个错误,并用 bsxfun 这是执行此类操作的非常有效的功能.对于Matlab R2016b或更高版本,您还可以隐式扩展而不是bsxfun.
我从滑动窗口的实现开始.除了使用for循环,还可以使用

Here's a new approach to achieve the result that you actually wanted to achieve. I corrected 2 mistakes that you made and replaced all the for loops with bsxfun which is a very efficient function to do stuff like this. For Matlab R2016b or newer you can also implicit expansion instead of bsxfun.
My starts at you implementation of the sliding window. Instead of your for-loop, you can use

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个windo.这些行需要转换为a -array的线性索引,以便获取可以传递给std -function的值的数组.在您的实现中,您在这里犯了一个小错误,因为您的for循环在size(a,1)-window_size处结束,并且实际上应该已经在size(a,1)-overlap处结束,因为否则您将错过最后一个窗口.
现在我们已经获得了窗口的std值,我们可以检查哪些窗口大于您的预定义阈值,然后将它们转换回相应的行:

here. The bsxfun creates an array that holds the rows of your windows. It holds 1 windo in each column. These rows need to be transformed into linear index of the a-array in order to get an array of values, that can be passed to the std-function. In your implementation you made a small mistake here, because your for-loop ends at size(a,1)-window_size and should actually have ended at size(a,1)-overlap, because otherwise you are missing the last window.
Now that we got the std-values of the windows we can check which ones are greater than your predefined threshhold and then transform them back into the corresponding rows:

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

highStdWindows包含具有高Std值的窗口的索引.在下一行中,我们使用highStdWindows*step-step+1计算这些窗口的起始行,然后再次使用bsxfun计算与每个窗口相对应的其他行.
现在,我们来解决您的代码中的实际错误.这行就在这里

highStdWindows contains the indexes of the windows, that have high-Std-values. In the next line, we calculate the starting rows of these windows using highStdWindows*step-step+1 and then we calculate the other rows that are corresponding to each window using the bsxfun again.
Now we get to the actual mistake in your code. This line right here

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.您要写的是

does not do what you wanted it to do. Unfortunatly you missplaced a couple of brackets here. This way you take the large_windows(i)'th element of matrix a and substract 4*l_2_a_r_e from it. What you wanted to write was

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的线性索引. 不过,使用下标索引而不是线性索引可以更轻松地实现这一点:

This way you would substract the 4*l_2_a_r_e from the index that you pass to a. This would still be wrong, because in large_windows you stored row-numbers and not linear indexes corresponding to matrix a.
Nevertheless this can be achieved a lot easier using subscripted indexing instead of linear indexing:

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

这两条简单的线告诉matlab提取存储在highStdRows中的所有行以及所有列(由:表示).这样,如果有两个相邻的具有高Std值的窗口,您将获得两次重叠的行.如果您不想这样做,可以改用以下代码:

These two easy lines tell matlab to take all rows that are stored in highStdRows with all columns (expressed by the :). With this if there are two adjacent windows with high-Std-values you will get the overlapping rows twice. If you don't want that, you can use this code instead:

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

如果您想进一步了解Matlab中索引的工作原理,请看LuisMendo的

If you want to get further insides on how indexing in Matlab works take a look at LuisMendo's post about this topic.

这篇关于从矩阵A提取包含矩阵B元素的所有行的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆