Averaging non-aligned time-series arrays

3 visualizaciones (últimos 30 días)
dormant
dormant el 4 de Sept. de 2024
Respondida: Steven Lord el 8 de Oct. de 2024
I have four arrays of time series data, sampled at equal intervals. The arrays do not start or end at the same times. So I have eight arrays (time values are integers):
  • time1, data1
  • time2, data2
  • time3, data3
  • time4, data4
How can I create a mean time series from all four, covering the entire time range? I would assume NaN where there is no data.
For example, with two small time series:
time1 = [1 2 3 4];
data1 = [1 1 1 1];
time2 = [3 4 5];
data2 = [3 3 3];
I want the result:
timeMean = [1 2 3 4 5];
dataMean = [1 1 2 2 3]
I could do this with several loops, but is there an elegant way?

Respuesta aceptada

Zinea
Zinea el 5 de Sept. de 2024
Hi dormant ,
For creating a mean time series covering the entire time range, you can use a combination of ‘unique’, ‘ismember’, and vectorized operations to avoid explicit loops.
Given below are the functions used followed by the code assuming dummy values for the arrays:
  1. All time arrays are concatenated, and ‘unique’ is used to find all distinct time points.
  2. A ‘dataMean’ array is created and filled with ‘NaN’ values initially.
  3. For each unique point, the code checks which series contain data for that time, collects those values, and computes their mean ignoring ‘Nan” values.
% Define the time and data arrays
time1 = [1 2 3 4];
data1 = [1 1 1 1];
time2 = [3 4 5];
data2 = [3 3 3];
time3 = [2 3 4 5 6];
data3 = [2 2 2 2 2];
time4 = [1 2 6 7];
data4 = [4 4 4 4];
% Combine all time arrays and find the unique time points
allTimes = [time1, time2, time3, time4];
timeMean = unique(allTimes);
% Initialize the dataMean array with NaNs
dataMean = NaN(size(timeMean));
% Function to compute mean ignoring NaNs
nanmeanFunc = @(x) mean(x(~isnan(x)));
% Loop over each unique time point to compute the mean
for i = 1:length(timeMean)
currentTime = timeMean(i);
% Find data values corresponding to the current time in each series
dataValues = NaN(1, 4); % Assuming there are 4 data series
[~, idx1] = ismember(currentTime, time1);
if idx1 > 0
dataValues(1) = data1(idx1);
end
[~, idx2] = ismember(currentTime, time2);
if idx2 > 0
dataValues(2) = data2(idx2);
end
[~, idx3] = ismember(currentTime, time3);
if idx3 > 0
dataValues(3) = data3(idx3);
end
[~, idx4] = ismember(currentTime, time4);
if idx4 > 0
dataValues(4) = data4(idx4);
end
% Compute the mean of the available data values
dataMean(i) = nanmeanFunc(dataValues);
end
% Display the result
disp('timeMean = ');
disp(timeMean);
disp('dataMean = ');
disp(dataMean);
Output:
Hope this resolves the query!

Más respuestas (2)

dormant
dormant el 8 de Oct. de 2024
Apologies for not acknowledging all your answers. You've been a great help. So, thanks very much.

Steven Lord
Steven Lord el 8 de Oct. de 2024
If those integer arrays represent some amount of time (seconds since the start of whatever experiment you used to collect the data, for example) consider creating a duration array out of them (in that scenario I described above I'd use the seconds function) and using that duration array to create a timetable. If you do you can retime or synchronize to change the time basis of the timetable.

Categorías

Más información sobre Shifting and Sorting Matrices en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by