How to approach iterative data reading?
Mostrar comentarios más antiguos
I'm working with a dataset that has 3 different arrays I'm interested in plotting: time, accel, and gcamp. They are all of equal size.
I'm using the accel variable as a threshold detector, where I define an arbitrary threshold under which any data I ignore. Anything above that threshold I use the index of that data point to grab the equivalent data points from time and gcamp.
How can I store this data in one structure so that I can iterate through it and generate statistics/plots about only the thresholded data points?
Something like:
time = [rand(1, 5000)];
accel = [rand(1,5000)];
gcamp = [rand(1,5000)];
sd = std(accel);
threshold = sd;
dumb = [];
for i = 1:length(accel);
if accel(i) > threshold;
dumber = [time(i), gcamp(i)];
dumb = [dumb, dumber];
end
end
Respuesta aceptada
Más respuestas (1)
I am not certain what you want to do, however the logical vector approach (the 'Lv' variable here) is probably more efficient that the explicit loop.
One option to segregate the values after threshoding them is to find the beginning and end locations of each series of 1 values in Lv and use that to segment the signal. You can do whatever you want with the segments after that.
Try something like this --
% time = [rand(1, 5000)];
time = 0:4999;
accel = sin(time*2*pi/500);
gcamp = cos(time*2*pi/400);
sd = std(accel);
threshold = sd;
Lv = accel > threshold;
Valid = nnz(Lv)
timev = time(Lv);
gcampv = gcamp(Lv);
% Lv
startv = strfind(Lv, [0 1]) + 1;
stopv = strfind(Lv, [1 0]);
if startv(1) > stopv(1)
startv = [1 startv];
end
if numel(startv) > numel(stopv)
stopv = [stopv numel(Lv)];
end
for k = 1:numel(startv)
idxrng = startv(k):stopv(k);
ixr{k} = idxrng([1 end]);
segment{k} = [time(idxrng); gcamp(idxrng)];
end
ixr{1}
segment{1}
ixr{2}
segment{2}
ixr{end}
segment{end}
figure
hold on
for k = 1:numel(segment)
plot(segment{k}(1,:), segment{k}(2,:))
end
hold off
grid
showMissing = zeros(size(time)) - 0.2;
showMissing(Lv) = 0.2 * ones(1,Valid);
figure
plot(time, gcamp)
hold on
plot(time, showMissing, 'r')
hold off
grid
figure
stairs(time, gcamp, '-')
hold on
stairs(time, showMissing, '-r')
hold off
grid
xlim([1000 1900])
ylim([-1.1 1.1])
% dumb = [];
% for i = 1:length(accel);
% if accel(i) > threshold;
% dumber = [time(i), gcamp(i)];
% dumb = [dumb, dumber];
% end
% end
.
3 comentarios
Eric
hace 34 minutos
Star Strider
hace 19 minutos
It's not generated code. I wrote it. It's original to your question, although I've used similar code for similar problems..
I use strfind because it works in this instance. There are other ways to test for the beginning and end of the 1 series occurrences, however this is the easiest and most efficient.
With respect to the plots, they simply illustrate what my code does, considering that you stated 'How can I store this data in one structure so that I can iterate through it and generate statistics/plots about only the thresholded data points?' The 'one structure' in my code is the 'segments' cell array. (I chose that name rather than 'dumber'. Change its name to whatever you want.)
My code might have to be tweaked slightly to work precisely with your data, however in all likelihood, it should work without modification. Remove the two if blocks if you don't need them.
Walter Roberson
hace 1 minuto
It turns out that strfind has a no-longer-documented behaviour of searching for patterns in numeric arrays.
strfind(NUMERIC_ARRAY, PATTERN)
has the behaviour of searching within NUMERIC_ARRAY looking for positions that match the contents of PATTERN, locations where
all(NUMERIC_ARRAY(K:K+length(PATTERN)-1) == PATTERN(1:end))
and returning all of the K that the condition matches for.
It is common to use this to match between two logical arrays, or between double precision arrays and logical arrays, such as
strfind(X >= 1, [0 1 1 1])
being the command to search X for transitions between values less than 1 and a group of at least 3 places that are greater than or equal to 1. Likewise,
strfind(X >= 1, [1 1 1 0])
would search for locations where at least 3 positions in a row were greater than or equal to 1, followed by a position where the condition was false.
When you put two strfind() together, you can get the locations of starts of runs in one call, and the locations of ends of runs in another call.
You do have to be careful to add (one less than the length of the pattern) to the returned indices to get the actual location of the ends of runs. You have to double-check the logic to distinguish between the last location that is within a run, compared to the first location that is after the run, both of which are valid things to want to search for.
@Star Strider uses comparison logic to determine boundary conditions. I personally prefer to use logic such as
strfind([false, X>= 1], [0 1 1 1])
if I want leading runs of >= 1 to be considered to match. After all, there are times when (for example)
[3 8 2 1 -2 -1 4 9 13]
sometimes you want the pattern X>=1 to be considered to start immediately at the beginning of the array, and sometimes you do not want it to be considered to start until the -1 4 9 13
Categorías
Más información sobre MAB Modeling Guidelines en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


