从矩阵 A 中提取包含矩阵 B 元素的所有行的更好方法
Better way to extract all the rows from a Matrix A that contain an element of a matrix B
矩阵 A 是我的起始矩阵,它保存从我的 MPU6050 和 GPS 记录到 SD 卡上的数据(纬度、经度、时间、Ax、Ay、Az、Gx、Gy、Gz)。
我计算了 window 大小为 5 的 Az 的标准偏差,并确定了满足条件(> 阈值)的所有元素。
然后在矩阵"large_windows"中存储了window中所有满足条件的Az的索引。
从矩阵 "large_windows" 我计算了一个新矩阵 B,其中包含矩阵 A 中包含矩阵 "large_windows"[ 的所有行=51=] 元素。
我认为我的代码是effective, but very ugly and chaotic, plus i am still not very practical with indexing,但我想学习它。
1.是否存在更好的解决方案?
2。可以使用逻辑索引吗?如何?效率高*?
这是我的代码,是一个简化的示例,具有通用条件,不仅可以更好地理解整个概念,而且不仅是我的具体情况,
%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 不包含在 A 中,所以这个问题没有帮助
I don't know how to use ismember
在这种情况下
希望我的图能更好的说明我的问题:)
感谢您的宝贵时间
这是一种实现您实际想要实现的结果的新方法。我纠正了您犯的 2 个错误,并将所有 for 循环替换为 bsxfun
which is a very efficient function to do stuff like this. For Matlab R2016b or newer you can also implicit expansion 而不是 bsxfun
。
我从您执行滑动 window 开始。您可以使用
而不是 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 创建一个数组,其中包含 windows 的行。它在每列中包含 1 个窗口。这些行需要转换为 a
-array 的线性索引,以便获得可以传递给 std
-function 的值数组。在您的实现中,您在这里犯了一个小错误,因为您的 for
循环在 size(a,1)-window_size
结束并且实际上应该在 size(a,1)-overlap
结束,否则您将错过最后一个 window .
现在我们得到了 windows 的标准值,我们可以检查哪些值大于您预定义的阈值,然后将它们转换回相应的行:
highStdWindows=find(std_vals_2>threshold);
highStdRows=bsxfun(@plus,highStdWindows*step-step+1,(0:3).');
highStdWindows
包含具有高标准值的 windows 的索引。在下一行中,我们使用 highStdWindows*step-step+1
计算这些 windows 的起始行,然后我们再次使用 bsxfun
计算与每个 window 对应的其他行。
现在我们来看看您的代码中的实际错误。这条线就在这里
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
中的所有行和所有列(由 :
表示)。有了这个,如果有两个相邻的 windows 具有高标准值,您将获得两次重叠行。如果您不想这样,可以改用此代码:
rowList=unique(reshape(highStdRows,1,[]));
C=a(rowList,:);
如果您想进一步了解 Matlab 中索引的工作原理,请查看 LuisMendo 关于此主题的 post。
矩阵 A 是我的起始矩阵,它保存从我的 MPU6050 和 GPS 记录到 SD 卡上的数据(纬度、经度、时间、Ax、Ay、Az、Gx、Gy、Gz)。
我计算了 window 大小为 5 的 Az 的标准偏差,并确定了满足条件(> 阈值)的所有元素。
然后在矩阵"large_windows"中存储了window中所有满足条件的Az的索引。
从矩阵 "large_windows" 我计算了一个新矩阵 B,其中包含矩阵 A 中包含矩阵 "large_windows"[ 的所有行=51=] 元素。
我认为我的代码是effective, but very ugly and chaotic, plus i am still not very practical with indexing,但我想学习它。
1.是否存在更好的解决方案?
2。可以使用逻辑索引吗?如何?效率高*?
这是我的代码,是一个简化的示例,具有通用条件,不仅可以更好地理解整个概念,而且不仅是我的具体情况,
%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 不包含在 A 中,所以这个问题没有帮助
I don't know how to use ismember
在这种情况下
希望我的图能更好的说明我的问题:)
感谢您的宝贵时间
这是一种实现您实际想要实现的结果的新方法。我纠正了您犯的 2 个错误,并将所有 for 循环替换为 bsxfun
which is a very efficient function to do stuff like this. For Matlab R2016b or newer you can also implicit expansion 而不是 bsxfun
。
我从您执行滑动 window 开始。您可以使用
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 创建一个数组,其中包含 windows 的行。它在每列中包含 1 个窗口。这些行需要转换为 a
-array 的线性索引,以便获得可以传递给 std
-function 的值数组。在您的实现中,您在这里犯了一个小错误,因为您的 for
循环在 size(a,1)-window_size
结束并且实际上应该在 size(a,1)-overlap
结束,否则您将错过最后一个 window .
现在我们得到了 windows 的标准值,我们可以检查哪些值大于您预定义的阈值,然后将它们转换回相应的行:
highStdWindows=find(std_vals_2>threshold);
highStdRows=bsxfun(@plus,highStdWindows*step-step+1,(0:3).');
highStdWindows
包含具有高标准值的 windows 的索引。在下一行中,我们使用 highStdWindows*step-step+1
计算这些 windows 的起始行,然后我们再次使用 bsxfun
计算与每个 window 对应的其他行。
现在我们来看看您的代码中的实际错误。这条线就在这里
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
中的所有行和所有列(由 :
表示)。有了这个,如果有两个相邻的 windows 具有高标准值,您将获得两次重叠行。如果您不想这样,可以改用此代码:
rowList=unique(reshape(highStdRows,1,[]));
C=a(rowList,:);
如果您想进一步了解 Matlab 中索引的工作原理,请查看 LuisMendo 关于此主题的 post。