Create 30 minute bins by reading time stamps

12 ビュー (過去 30 日間)
Bradley
Bradley 2023 年 12 月 13 日
コメント済み: Mathieu NOE 2023 年 12 月 19 日
I have a file with time stamps, due to error in the files (gaps in time due to faulty equipment) binning 30 minute sections using the following code creates errors in the actograms produced.
function[Average] = Av_30min(y)
Average = zeros(288,size(y,2));
k = 1;
for l =1:288
Average(l,1) = mean(y(k:k+(round(length(y)/288)-1),1));
k = k+((round(length(y)/288)-1));
end
end
I want to read from say 11:30:00 - 12:00:00 and average this bin and so on and so forth. Can anyone help?
Thanks

採用された回答

Star Strider
Star Strider 2023 年 12 月 14 日
What do the ‘Calculated time’ values represent? Are they fractions of a day (from about ¼ to about 3¼ days) or something else?
Until that is resolved, converting them into something useful is not likely to be possible.
Here, I used sortrows and then fillmissing and resample to create some sort of order.
% imshow(imread('Timestamps in output.PNG'))
% function readfaultydata
% clear; close all
Data = xlsread('Data.xlsx',1,'A2:F60099');
T1 = readtable('Data.xlsx', 'VariableNamingRule','preserve');
t = Data(:,1);
dt = t(2)-t(1); % Your sample rate
t = (1:length(t))*dt; % Linear timeline
x = Data(:,3);
y = Data(:,4);
z = Data(:,5);
subplot(311);plot(t,x);grid;
subplot(312);plot(t,y);grid;
subplot(313);plot(t,z);grid;
T1 = sortrows(T1,1);
T1 = fillmissing(T1, 'nearest') % Sorted With NaN Values Interpolated
T1 = 60103×9 table
Calculated time Device X Y Z LDR Var7 Var8 Var9 _______________ __________ __ __ __ ___ ______ _______ _______ 0.26653 {'BSB_6A'} 0 70 56 0 0.2611 0.85946 0.96134 0.26664 {'BSB_6A'} 0 61 72 0 0.2611 0.85946 0.96134 0.26676 {'BSB_6A'} 5 57 67 0 0.2611 0.85946 0.96134 0.26687 {'BSB_6A'} 9 28 57 0 0.2611 0.85946 0.96134 0.26699 {'BSB_6A'} 60 0 44 0 0.2611 0.85946 0.96134 0.26711 {'BSB_6A'} 62 52 57 0 0.2611 0.85946 0.96134 0.26722 {'BSB_6A'} 48 36 70 0 0.2611 0.85946 0.96134 0.26734 {'BSB_6A'} 66 33 63 0 0.2611 0.85946 0.96134 0.26745 {'BSB_6A'} 70 50 60 0 0.2611 0.85946 0.96134 0.26757 {'BSB_6A'} 34 26 56 0 0.2611 0.85946 0.96134 0.26769 {'BSB_6A'} 51 47 75 0 0.2611 0.85946 0.96134 0.2678 {'BSB_6A'} 17 56 64 0 0.2611 0.85946 0.96134 0.26792 {'BSB_6A'} 50 40 29 0 0.2611 0.85946 0.96134 0.26803 {'BSB_6A'} 26 65 79 0 0.2611 0.85946 0.96134 0.26815 {'BSB_6A'} 22 73 85 0 0.2611 0.85946 0.96134 0.26826 {'BSB_6A'} 51 70 79 0 0.2611 0.85946 0.96134
VN = T1.Properties.VariableNames;
% timestats = [mean(diff(T1{:,1})) std(diff(T1{:,1}))]
Ts = mean(diff(T1{:,1}))
Ts = 4.9837e-05
Fs = 1/Ts
Fs = 2.0065e+04
Fn = Fs/2;
[XYZr, tr] = resample(T1{:,[3 4 5]}, T1{:,1}, Fs);
% format longg
% XYZr(end-4:end,:)
XYZr = XYZr(1:end-3,:);
tr = tr(1:end-3);
% XYZr(end-4:end,:)
x = XYZr(:,1);
y = XYZr(:,3);
z = XYZr(:,3);
figure
plot(tr, XYZr)
grid
xlabel([string(VN{1}) + " (Sorted & Resampled)"])
ylabel("Amplitude")
figure
tiledlayout(3,1)
for k = 1:size(XYZr,2)
nexttile
plot(tr, XYZr(:,k))
grid
ylabel("Amplitude")
title(["Column "+k])
end
xlabel([string(VN{1}) + " (Sorted & Resampled)"])
figure
scatter3(x,y,z, 10, z, '.')
colormap(turbo)
grid on
xlabel('X')
ylabel('Y')
zlabel('Z')
.
  7 件のコメント
Bradley
Bradley 2023 年 12 月 18 日
Thank you very much! This works perfectly!
Star Strider
Star Strider 2023 年 12 月 18 日
My pleasure!
If my Answer helped you solve your problem, please Accept it!
.

サインインしてコメントする。

その他の回答 (2 件)

Alexander
Alexander 2023 年 12 月 13 日
Whers is this file Data.xlsx from? I think someone has corrupted the "Calculated time" column. In this column is a mixture of formulars and manual input (see cell A1793:A1795, e.g.). If you copy A3 and paste it to A60099 your timeline is correct your program might run (I'll attach a modified xlsx). Hopefully this was your intension.
  2 件のコメント
Bradley
Bradley 2023 年 12 月 14 日
Hi Alexander,
Thanks for the suggestion but that is exactly the issue, if the data ran sequentially then my analytical code would have worked fine, but alas here we are trying to find another solution to atleast make some use of this data.
Alexander
Alexander 2023 年 12 月 14 日
Here some code, w/o editing the xlsx:
function readfaultydata
clear; close all
Data = xlsread('Data.xlsx',1,'A2:F60099');
t = Data(:,1);
dt = t(2)-t(1); % Your sample rate
t = (1:length(t))*dt; % Linear timeline
x = Data(:,3);
y = Data(:,4);
z = Data(:,5);
subplot(311);plot(t,x);grid;
subplot(312);plot(t,y);grid;
subplot(313);plot(t,z);grid;
end
Hope it helps.

サインインしてコメントする。


Mathieu NOE
Mathieu NOE 2023 年 12 月 13 日
hello
this is certainly not the best and most modern way to solve your problem , but as I have not really started digging with timetables and alike , so here's a (very) low level approach
someone younger / smarter may come up with a 2 lines solutions, but for the time being this is what I can offer
in very short , I am simply looking where 30 or 00 min appears in your data and the duration is exactly 180 samples (= 30 mins) then this data is averaged and saved
the new time data correspond to the beginning of the 30 min buffer
also I didn't copy paste the header line, I think you could manage that by yourself...
result should look like :
code
y = xlsread('Data.xlsx');
%% convert y firt column (time HH:MM:SS) to hours (h), minutes (m) and seconds (s)
h = y(:,1)*24;
m = 60*(h - floor(h));
s = 60*(m - floor(m));
h = floor(h);
m = floor(m);
s = round(s);
id1 = (m ==30); % find time index matching the 30 min timestamp
[begin1,ends1] = find_start_end_group(id1);
id2 = (m ==00); % find time index matching the 00 min timestamp
[begin2,ends2] = find_start_end_group(id2);
begin = sort([begin1;begin2]); % concat all index corresponding to 00 or 30 min time stamps
%% main loop
k = 0;
for ci = 1:numel(begin)-1
ind_start = begin(ci);
ind_stop = begin(ci+1);
samples = ind_stop - ind_start;
if samples == 180 % only valid segments are processed
k = k+1;
data = y(ind_start:ind_stop,2:end);
mean_data{k,1} = mean(data,'omitnan');
date{k,1} = [sprintf('%02d', h(ind_start)) ':' sprintf('%02d', m(ind_start)) ':' sprintf('%02d', s(ind_start))]; % a very crude method to create the time string
end
end
% export the data
out = [date mean_data];
writecell(out,'toto.xlsx');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [begin,ends] = find_start_end_group(ind)
% This locates the beginning /ending points of data groups
% Important : ind must be a LOGICAL array
D = diff([0;ind(:);0]);
begin = find(D == 1);
ends = find(D == -1) - 1;
end
  4 件のコメント
Bradley
Bradley 2023 年 12 月 19 日
Thanks Mathieu. If you see above Star Strider has answered this in a more succint way.
Mathieu NOE
Mathieu NOE 2023 年 12 月 19 日
I know I would not win this time (again !)

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeStartup and Shutdown についてさらに検索

タグ

製品


リリース

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by