How do I delete a group of rows when a condition is met in one?
4 views (last 30 days)
Show older comments
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 Comments
Answers (2)
David Hill
on 7 Sep 2022
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 Comments
Fifteen12
on 7 Sep 2022
Edited: Fifteen12
on 13 Sep 2022
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 Comments
Fifteen12
on 13 Sep 2022
Edited: Fifteen12
on 13 Sep 2022
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.
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!