Iterate and convert datenums to date times, and find time durations

1 visualización (últimos 30 días)
Joy Shen
Joy Shen el 18 de Nov. de 2021
Comentada: Peter Perkins el 24 de Nov. de 2021
I have a matrix with wave heights (feet) that change over time. The time is a datenum in the form of yyyymmddHHMM. I need to find the times where the wave height is above a threshold, let's say 5 feet. So I need two things: How do I loop through the array and convert the datenums to datetimes? How do I find the time where the wave height crosses the threshold and goes below the threshold. (I need this to find the time duration that the wave height is above the threshold)
This is what I have so far. It doesn't really work though...
Thanks in advance.
% T is the datenum array
% Waveht is the Wave height array
%% Converting datenum array to date time array
vec1 = datevec('200007130000','yymmddHHMMSS'); %I'm not sure how to iterate through the datetime since this is a string input
a = datetime(vec);
%% polyxpoly
y_line = repelem(5,length(a)); %Creating the threshold line since polyxpoly needs an x value.
x = 0:1:length(a);
y1 = [T Waveht]
y_ps = [x y_line];
[xint1,yint1] = polyxpoly(y1,y_ps)
  2 comentarios
KSSV
KSSV el 18 de Nov. de 2021
You can use datetime class and use logicals to get what you want. If time is your datetime and h is wave height.
idx = h > 5 ;
t = time(idx) ;
You can loop through datetime class, you need not to worry about it.

Iniciar sesión para comentar.

Respuestas (1)

Peter Perkins
Peter Perkins el 23 de Nov. de 2021
A couple of preliminaries:
xlsread is not recommended. readtimetable is what you want.
'200007130000' isn't a "datenum", that term means something very specific in MATLAB. Also 'yymmddHHMMSS' can't be write unless you are using zero-based month numbers, which ... don't. To convert that string to a datetime just do this (I'm just guessing on the format):
>> datetime('200007130000',"InputFormat","yyyyMMddHHmm","Format","yyyy-MMM-dd HH:mm")
ans =
datetime
2000-Jul-13 00:00
So given that, you may not actually be able to use readtimetable, you may need to use readtable to read those timestamps in as text, and then convert them as above, and then use table2timetable.
OK, so you have a timetable, named tt. I don't really know specifically what you mean by "I need the time durations that the component is in operation, above a certain height", but you can use old-school logical operations to find runs of heights > threshold, and then use timetable and table operations to get their durations.
First set up some fake data.
>> WaveHeight = sin(0:.5:50)';
>> tt = timetable(WaveHeight,'TimeStep',minutes(1));
>> %plot(tt.Time,tt.WaveHeight);
>> H = .4;
Now find the rows of that timetable with tall waves, then find the start and end of the runs of tall waves, then remove all the other rows.
>> overThreshold = tt.WaveHeight > H; % rows of tt with height > H
>> tt.RunStarts = [false; diff(overThreshold)>0]; % rows of tt where height grew over H
>> tt.RunEnds = [diff(overThreshold)<0;false]; % rows of tt where height grew over H
>> tt.RunNumber = cumsum(tt.RunStarts) .* overThreshold;
>> runs = tt(tt.RunStarts | tt.RunEnds,["RunStarts" "RunEnds" "RunNumber"])
runs =
16×3 timetable
Time RunStarts RunEnds RunNumber
______ _________ _______ _________
1 min true false 1
5 min false true 1
14 min true false 2
18 min false true 2
26 min true false 3
30 min false true 3
39 min true false 4
43 min false true 4
52 min true false 5
55 min false true 5
64 min true false 6
68 min false true 6
77 min true false 7
80 min false true 7
89 min true false 8
93 min false true 8
Now set things up conveniently, and se unstack to reorganize the data to have each row represent one run, and get the durations.
>> runs.RunStartEnd = categorical(1*runs.RunStarts + 2*runs.RunEnds,[1 2],["Start" "End"]);
>> runs.RunStarts = [];
>> runs.RunEnds = []
runs =
16×2 timetable
Time RunNumber RunStartEnd
______ _________ ___________
1 min 1 Start
5 min 1 End
14 min 2 Start
18 min 2 End
26 min 3 Start
30 min 3 End
39 min 4 Start
43 min 4 End
52 min 5 Start
55 min 5 End
64 min 6 Start
68 min 6 End
77 min 7 Start
80 min 7 End
89 min 8 Start
93 min 8 End
>> runs = timetable2table(runs);
>> runs = unstack(runs,"Time","RunStartEnd");
>> runs.Duration = runs.End - runs.Start
runs =
8×4 table
RunNumber Start End Duration
_________ ______ ______ ________
1 1 min 5 min 4 min
2 14 min 18 min 4 min
3 26 min 30 min 4 min
4 39 min 43 min 4 min
5 52 min 55 min 3 min
6 64 min 68 min 4 min
7 77 min 80 min 3 min
8 89 min 93 min 4 min
I'm just guessing at what you have and what you want, but this should get you started.
  2 comentarios
Joy Shen
Joy Shen el 23 de Nov. de 2021
Hi Peter, thanks for this extensive answer. I see what you mean, so run number is basically my component ID?
My data looks like this if it clarifies anything:
Comp ID Date Height
_________ ____________ ______
1 200007152311 2
1 200007152312 3
1 200007152313 4
1 200007152314 1
2 200007141111 0
2 200007151113 1
3 200007131115 0
3 200007141111 5
And how do I input the column of date strings to convert into datetime?
Date = datetime(T1(:,8),"InputFormat","yyyyMMddHHmm","Format","yyyy-MMM-dd HH:mm")
This obviously gets me an error.
Peter Perkins
Peter Perkins el 24 de Nov. de 2021
I don't know what your component ID is.
And I can only guess what error you are seeing. Is it because your table doesn't have 8 variables? The one you show has 3. Is it because you've passed an Nx1 table into the datetime function, not the timestamps themselves? Is it because your timestamps are numeric, not text? The Date variable in the table you show is either numeric, or a big char matrix, which is a bad idea and I don't know how you landed there.
You are not providing enough information to go on.

Iniciar sesión para comentar.

Categorías

Más información sobre Dates and Time en Help Center y File Exchange.

Productos


Versión

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by