Extract data between thresholds
10 views (last 30 days)
Show older comments
Hi everyone,
I'm encountering a problem with my data analysis and hope to find some solution. I already gave a look at other threads to see if anyone had the same problem and resolved it, but no one aimed to do what I intend to.
In short, I have these data in csv (or txt) format that can be graphically represented here :
I would like to index these data into 4 different arrays, one for each period.
With
[row]=find(filename==0)
I can identify where the 0s are and then manually index the data, but as I have a lot of files I would like to automate it. I could put thresholds but I have 2 criteria for them :
For stop threshold :
- value contained in cell 1 > cell2
- cell 2 = 0
For start threshold :
- value contained in cell 1 < cell 2
- cell 1 = 0
As you can see, thresholds can't be a fixed value, and I have more than one period to identify, hence I'm having difficulty. I'm far from a Matlab expert so maybe I'm missing something easy, in that case I would gladly appreciate your help.
Thank you in advance !
2 Comments
Accepted Answer
More Answers (1)
Julius Muschaweck
on 9 Apr 2021
I believe logical indexing and the diff function are what you need.
% create and plot something like your data
x = 0:300; % some x value
y = - cos(x * 8 * pi / 300); % about 4 full cosine cycles, the minus sign makes it start at -1
y ( y<0 ) = 0; % use logical indexing to set negative values to zero
figure(); % looks somewhat like your data
plot(x,y);
axis([-Inf Inf -0.1 Inf]); % make sure the y=0 lines are visible
% manual inspection of y reveals that you want index ranges 20:57, 95:132 etc
dy = diff(y); % difference between adjacent elements -- the first part of your conditions
% extend dy to enable logical operation on same size arrays
dystart = [dy,0]; % dystart(i) is y(i+1) - y(i) -- your start condition
dystop = [0,dy]; % dystop(i) is y(i) - y(i-1) -- your start condition
justbeforestart = (y == 0) & (dystart > 0); % your start condition
justafterstop = (y == 0) & (dystop < 0); % your stop condition
% both just... arrays have same length as x, mostly 0, only 1 where condition is detected
% extract the start and stop indices
idx = 1:length(x); % the array of indices
% use logical indexing again to extract start/stop indices
startidx = idx(justbeforestart) + 1; % add 1 to get actual "start" from "justbeforestart"
stopidx = idx(justafterstop) - 1; % subtract 1 to get "stop"
% sanity checks
if y(1) ~= 0 || y(end) ~= 0
error(' data must start and end with zero ');
end
if length(startidx) ~= length(stopidx)
error(' must have same number of starts and stops ');
end
% extract the four data ranges and put them into a cell array
my_arrays = {};
for i = 1:length(startidx)
% create a struct with fields x and y for each data range
s.x = x(startidx(i) : stopidx(i) );
s.y = y(startidx(i) : stopidx(i) );
my_arrays{i} = s;
end
% plot the four individual ranges
% note that the zero values are missing, just like they should.
figure();
hold on;
for i = 1:length(my_arrays)
t = my_arrays{i};
plot(t.x, t.y);
end
axis([x(1) x(end) -0.1 1.1]);
See Also
Categories
Find more on Matrix Indexing 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!