How to count how often a variable returns to zero and then increases from zero

6 views (last 30 days)
Hi everyone, imagine you have a table of Time and a Y variable, could be anything, current, voltage, torque etc. What would be the best way to code MATLAB to count how often the value goes down to zero and then increases above zero again? E.g.
Time Voltage
_____ _____
1 3
2 2
3 1
4 0
5 1
6 0
7 2
8 3
9 0
10 3
11 3
12 2
13 1
14 0
15 1
16 0
17 2
18 3
19 0
So you can see sometimes the voltage starts to rise, and then it drops, and eventually hits 0, and then starts to rise, and then starts to fall, and then hits zero etc.I want some kind of counter that would increase every time the value drops to zero (or some threshold) and then increases above the threshold again.
  4 Comments
Alexander
Alexander on 22 Feb 2024
OK. Just for my understanding: What should be the outcome of your (19) lines you have shown above?
Alexander
Alexander on 22 Feb 2024
And another question: What do you mean with "pretty arbitraty"? I think you can't work with a threshold you have no idea about it.

Sign in to comment.

Answers (2)

John D'Errico
John D'Errico on 21 Feb 2024
Edited: John D'Errico on 21 Feb 2024
It appears this parameter never goes negative.
Are your sets ALWAYS such that a zero is always alone? So when it hits zero, it never stays there?
If this is true, then just count the number of zeros. If a zero as the very first or last element does not count, then subtract 1 if the first element is a zero. Subtract 1 if the last element is a zero.
It seems trivial. If there are cases where the variable stays at zero, then just subtract 1 from the count whenever a zero is followed by another zero.
Again, all of this is trivial. As far as being in a table, just extract that variable from the table. Tables are not the only variable type in MATLAB, and tables often make your work far more difficult. So for the computation, just extract that variable as a vector. LEARN TO USE MATLAB. If all you ever do is use tables, you are just using MATLAB as a pseudo-spreadsheet. For example:
V = randi([0,3],[1,20])
V = 1x20
0 2 1 3 0 2 0 1 0 0 0 3 0 3 3 0 3 1 0 1
Zcount = sum(V == 0) % how many zeros?
Zcount = 9
Zcount = Zcount - (V(1) == 0) - (V(end) == 0) % Discard a zero at an end
Zcount = 8
Next, we need to discard multiple consecutive zeros in that count, But I assume that a sequence like [1 0 0 1] still counts as one event when it hit zero. How can we do that? Just search for any pairs of consecutive zeros.
Zcount = Zcount - numel(strfind(V,[0 0]))
Zcount = 6
So if we had a string like [1 0 0 0 1], we would find TWO consecutive pairs of zeros, but still one event. In fact, in the random string you see above, there was an initial zero. I discarded that from the count. Then there was a tripleton zero, so I cut the count by 2. In the end, there were exactly 6 events of the class you want to see.
I think this is what you want to see, but you should understand from my explanations if some of those tests are not what you wanted.
When you don't know how to solve a problem, start by finding something that might get you close to a solution. Can you then modify that? Make it better? Get you closer to a solution. Many problems in MATLAB can be resolved this way.
  2 Comments
AluminiumMan
AluminiumMan on 21 Feb 2024
Edited: AluminiumMan on 21 Feb 2024
Yes the parameter never drops below zero. But it can remain at zero for multiple data points in a row. I just didn't do that in the example. The counter would need to not increase unless the variable rose above a threshold and then dropped below it again
The data also contains millions of data points. You can't just count the zeros.
And you can have decimel points. So the data could go 0 0 0 0 0 0.1 0 0 5 and you would only count 1
It may seem trivial to you but I am struggling with this :-D
Voss
Voss on 22 Feb 2024
"The data also contains millions of data points. You can't just count the zeros."
Sure you can.
% a vector of a billion elements, each of which is zero or one:
v = randi([0,1],1e9,1);
% count the zeros and time how long it takes to do so:
t = tic();
n_zeros = nnz(v == 0);
dt = toc(t);
% display the number of zeros and the time it took to count them:
disp(sprintf('It took %g seconds to count %d zeros.',dt,n_zeros))
It took 1.14198 seconds to count 499966702 zeros.
Did you try the answer?

Sign in to comment.


Star Strider
Star Strider on 21 Feb 2024
One method to find the first instance of a zero value is to use the strfind function. You can use it again to determine the indices of a return from a zero value, then use those results to determine the start and end indices of the non-zero values. If you want the non-zero values themselves, use accumarray to retrieve them, then if necessary, edit the results —
A = [ 1 3
2 2
3 1
4 0
5 1
6 0
7 2
8 3
9 0
10 0
11 0
12 3
13 3
14 2
15 1
16 0
17 1
18 0
19 2
20 3
21 0];
TV = array2table(A, 'VariableNames',{'Time','Voltage'})
TV = 21×2 table
Time Voltage ____ _______ 1 3 2 2 3 1 4 0 5 1 6 0 7 2 8 3 9 0 10 0 11 0 12 3 13 3 14 2 15 1 16 0
Vv = TV.Voltage ~= 0
Vv = 21×1 logical array
1 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 0 1 1 0
zero_start = strfind(Vv.', [1 0])+1
zero_start = 1×6
4 6 9 16 18 21
zero_end = strfind(Vv.', [0 1])
zero_end = 1×5
4 6 11 16 18
nz = cumsum(TV.Voltage == 0) + 1;
TVNZ = accumarray(nz, (1:numel(nz)).', [], @(x){TV(x(TV{x,2}~=0),:)})
TVNZ = 9×1 cell array
{3×2 table} {1×2 table} {2×2 table} {0×2 table} {0×2 table} {4×2 table} {1×2 table} {2×2 table} {0×2 table}
Lv = cellfun(@(x)~isempty(x),TVNZ);
Result = TVNZ(Lv);
Result{:}
ans = 3×2 table
Time Voltage ____ _______ 1 3 2 2 3 1
ans = 1×2 table
Time Voltage ____ _______ 5 1
ans = 2×2 table
Time Voltage ____ _______ 7 2 8 3
ans = 4×2 table
Time Voltage ____ _______ 12 3 13 3 14 2 15 1
ans = 1×2 table
Time Voltage ____ _______ 17 1
ans = 2×2 table
Time Voltage ____ _______ 19 2 20 3
I’m not certain what result you want, however one of these should provide an approach to it.
.

Community Treasure Hunt

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

Start Hunting!