Averaging non-aligned time-series arrays

3 次查看(过去 30 天)
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?

采纳的回答

Zinea
Zinea 2024-9-5
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!

更多回答(2 个)

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

Steven Lord
Steven Lord 2024-10-8
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.

类别

Help CenterFile Exchange 中查找有关 Shifting and Sorting Matrices 的更多信息

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by