Extract data between thresholds

10 次查看(过去 30 天)
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 !

采纳的回答

KSSV
KSSV 2021-4-9
编辑:KSSV 2021-4-9
A = load('test.txt') ;
A = A' ;
ii = zeros(size(A));
jj = A > 0;
ii(strfind([0,jj(:)'],[0 1])) = 1;
idx = cumsum(ii).*jj;
out = accumarray( idx(jj)',A(jj)',[],@(x){x'});
celldisp(out)
You got all the four arrays in out.
  1 个评论
Gaëlle Broca
Gaëlle Broca 2021-4-9
Thank you, it was definitely what I needed, and definitely not close to what i found beforehand so I'm glad I asked.

请先登录,再进行评论。

更多回答(1 个)

Julius Muschaweck
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]);
  1 个评论
Gaëlle Broca
Gaëlle Broca 2021-4-9
A very different take than previous answer, I'll look into it deeper, thank you

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

产品


版本

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by