Combine multiple varying length double arrays into one timetable
41 次查看(过去 30 天)
显示 更早的评论
I have a .mat file with multiple (a few thousand) individual 2-column double arrays, all named for a different variable.
These arrays are of varying length (from a few to a few million rows), but for each of them the first column always is the timestamp in datenum format, the second column is the data.
I would like to get them into a single timetable where each column is the data from each array, with the column name taken from the variable name.
e.g.
log.mat
> Var1
> Time
> Data
> Var2
> Time
> Data
...
> VarN
> Time
> Data
into
Workspace
> TT
> Time
> Var1
> Var2
...
> VarN
I assume there has to be a better way of doing this than iteratively calling each variable from the .mat file, concatentating horizontally into one huge array, and then following this guide to convert it to a timetable?
1 个评论
dpb
about 1 hour 前
Pretty much @Voss gave the way; the problem is you have variable-length data arrays and a table or timetable must have same number of elements for each variable. This means you'll have to pad the shorter to the length of the longer.
And, unless the various variables also have consistent tmestamps, you'll also have to then synchronize the times to put the same variables at the same time in the table.
You can avoid having to write each variable name directly by using the functional form for load and return the variables as a struct, then you can iterate over the fieldnames in the stuct.
回答(2 个)
Stephen23
about 11 hours 前
编辑:Stephen23
about 10 hours 前
"I assume there has to be a better way of doing this than iteratively calling each variable..."
Note that synchronize accepts 1..N input timetables, which means you can synchronize all of them in one go. And that is probably what you should do, using a simple comma-separated list.
Fake data:
F1 = @(n) [datenum(2024,12,20,1,2,fix(600*rand(n,1))/10),randi(9,n,1)];
S.Var1 = F1(13);
S.Var2 = F1(1e2);
S.Var3 = F1(23)
Of course in your actual code you would LOAD into an output variable (which you should be doing anyway):
S = load(..);
Then synchronize:
F2 = @(a) array2timetable(a(:,2),'RowTimes',datetime(a(:,1),'ConvertFrom','datenum'));
C = struct2cell(structfun(F2,S, 'UniformOutput',false))
T = synchronize(C{:});
T.Properties.VariableNames = fieldnames(S)
0 个评论
Star Strider
about 1 hour 前
编辑:Star Strider
12 minutes 前
First, convert the datenum values to datetime arrays using the ConvertFrom='datenum' name-value pair, either reading each of them in as a timetable using the readtimetable function,or reading them in as a table and then using thee table2timetable function to convert them. I’m not certain what you want to do after that, however if I understand your question correctly, the synchronize function would be my approach. This can be done in a sinngle synchronize call, or it may be necesary to do this in a loop, adding each new timetable in each iteration.
EDIT — (20 Dec 2024 at 14:37)
That approach would look something like this —
TT{1} = timetable(datetime(2024,12,18)+hours(sort(rand(10,1)*10)), randn(10,1), VariableNames={'Voltage 1'});
TT{2} = timetable(datetime(2024,12,18)+hours(sort(rand(12,1))*10+4), randn(12,1), VariableNames={'Voltage 2'});
TT{3} = timetable(datetime(2024,12,19)+hours(sort(rand(8,1))), randn(8,1), VariableNames={'Voltage 3'});
for k = 1:numel(TT)
disp("height(TT{"+k+"} = "+height(TT{k}))
disp(TT{k})
end
TT_Combined = TT{1};
for k = 2:numel(TT)
TT_Combined = synchronize(TT_Combined, TT{k});
end
disp("size(TT_Combined = ["+size(TT_Combined,1)+" "+size(TT_Combined,2)+"]")
disp(TT_Combined)
Another approach could be:
TT_Combined = synchronize(cat(1,TT{:}))
However this synchronizes them all in to one timetable with one variable, not separate variables, so all the variable names would have to be the same.
.
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!