How do I delete a group of rows when a condition is met in one?
2 次查看(过去 30 天)
显示 更早的评论
Let's say I have a matrix which is 1000x1. When the value of a row > 0.25, I want to delete that row and 10 rows above and below. (e.g., of value of row 30 = 0.5, rwos 20-40 would be deleted). I have the follwoing starting point but not sure how to select the rows above and below.
data(data > 0.25,:) = []
0 个评论
回答(2 个)
David Hill
2022-9-7
f=find(data>.25);
idx=[];
for k=1:length(f)
idx=[idx,(f(k)-10):(f(k)+10)];
end
idx=unique(idx);
idx=idx(idx>0&idx<=length(data));
data(idx)=[];
0 个评论
Fifteen12
2022-9-7
编辑:Fifteen12
2022-9-13
Simple but long answer using an iterator:
Edits: Changed code to catch moving indices as data is resized and expand removal range if trigger values are found in the initial set.
data1 = randi(10,10,1);
threshold = 7;
clear_range = 2; %rows/samples
data = clearRange(data1, threshold, clear_range);
function [data] = clearRange(data, threshold, clear_range, compare_column)
% data: matrix of values to clean
% threshold: delete values greater than threshold
% clear_range: number of rows to delete
% compare_column: column to check for value to compare against threshold
if nargin < 4
compare_column = 1;
end
i = 1;
while i <= length(data)
if data(i,compare_column) > threshold
to_delete = [max(1, i-clear_range), min(length(data), i+clear_range)];
j = i + 1;
while j <= to_delete(2)
if data(j, compare_column) > threshold
to_delete = [to_delete(1), min(j + clear_range, length(data))];
end
j = j + 1;
end
data(to_delete(1):to_delete(2), :) = [];
i = max(1, i - clear_range);
else
i = i + 1;
end
end
end
3 个评论
Fifteen12
2022-9-13
编辑:Fifteen12
2022-9-13
Good catch. The problem was that the data matrix was being shifted every time a range was cleared, so the for loop was essentially jumping "clear_range" rows every time it was called.
There was an additional item of consideration where values over the threshold that are within the clearing range of another value are deleted before they can be considered by the algorithm. I've also edited the code to check each value before it's deleted, and extend the clearing range if a trigger value is found.
The code is pretty unoptimized, again, simple but slow in this case. You'd get much better performance by vectorizing. @David Hill's solution works fine and solves both of these problems with much better performance. I can't think of any reason to utilize mine versus his.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!