Time based moving average - is my approach correct?

조회 수: 7 (최근 30일)
Marc
Marc 2014년 5월 25일
편집: John Kelly 2017년 11월 10일
Hello Matlab folks,
I'd like to get a critique for my code because I am not sure if I am right. First of all, I have a set of data like
735728,605428241 80,6717800000000 11,6650710000000
735728,605451389 80,6717800000000 9,12566720000000
735728,605474537 80,1416200000000 9,24074830000000
735728,605497685 80,1416200000000 9,20919460000000
735728,605520833 80,1416200000000 9,47081590000000
735728,605543982 80,3848000000000 9,28115980000000
735728,605567130 80,3848000000000 8,55264740000000
735728,605590278 80,3848000000000 9,47107710000000
735728,605613426 80,5608400000000 9,42203640000000
735728,605636574 80,6196400000000 9,32575490000000
735728,605659722 80,6196400000000 9,25049830000000
735728,605682870 80,6998100000000 9,48914560000000
735728,605706019 80,6998100000000 9,52505890000000
735728,605729167 80,6998100000000 9,12462120000000
The first row is the time in format 'dd.mm.yyyy hh:mm:ss'. The sample rate is two seconds. Now I want to plane that data to get it a bit smoother and I want to do this by using a moving average of 60sec. To do so, I found the function movavg to be correct. I ended up with the following code
clc
clear all
close all
% Get the data
filepath=''; % Note: There is a path in the original code
fprintf('Path: %s\n', filepath)
fprintf('\nLoad totaldev ...\n')
totaldev = xlsread(strcat(filepath,'totaldev.xlsx'));
fprintf(' ...done!\nLoad plant_load ...')
plant_load = xlsread(strcat(filepath,'load.xlsx'));
fprintf(' ...done!\n')
data=[plant_load(:,1),plant_load(:,2),totaldev(:,2)];
data(:,1)=x2mdate(data(:,1));
fprintf('Prepare data ...\n')
% Remove values below 0 and above 100 (plant load is 0% to 100%
data(any(data(:,2)<0,2),:)=[];
data(any(data(:,2)>100,2),:)=[];
% Remove values below -100 and above 100 (error can't be more than +-100%)
data(any(data(:,3)<-100,2),:)=[];
data(any(data(:,3)>100,2),:)=[];
% Compute average of time series
% Sample rate is 2sec, so 30 values cover a minute
data_avg=[data(:,1), movavg(data(:,2),30,30), movavg(data(:,3),30,30)];
fprintf(' ...done!\n')
fprintf('\nCreate plot')
% Plot 'em
plot(data(:,1),data_avg(:,2),data(:,1),data_avg(:,3))
datetick('x','keepticks','keeplimits');
I'd like to know now if I did a mistake or if the average is wrong. Maybe someone can help.
Cheers from Germany
  댓글 수: 10
Cedric
Cedric 2014년 5월 26일
편집: Cedric 2014년 5월 26일
Hi Star Strider,
Ok. I'll think more about it, but my guess is that most of the usual methods will fail to produce a correct block average when there are missing data/entries. One solution could be to build a minuteID (=1 for the first n<=29 entries, =2 for the next 29 entries, etc ) before removing invalid entries, and then to use ACCUMARRAY on remaining entries, using the minuteID as a block ID..
Star Strider
Star Strider 2014년 5월 26일
Were it my data, I’d isolate the one-minute segments, do the thresholding on the selected block of data, compute the mean of the rest, and continue on. That just seems to me to be the easiest way to do the processing. I assume the data and times are continuous in every record.
I am prepared to stand corrected...

댓글을 달려면 로그인하십시오.

채택된 답변

Star Strider
Star Strider 2014년 5월 26일
My pleasure!
If you only need to run the loops once, saving the results of the one-minute-means in a ‘.mat’ file, a loop isn’t much of a problem since you only have to do it once.
Assuming your matrix to be X, it’s probably as easy as:
X = rand(180,3);
for k1 = 1:fix(size(X,1)/30)
for k2 = (k1-1)*30+1
Xm(k1,:) = mean(X(k2:k2+29,:));
end
end
That runs without error, with Xm storing the one-minute means. Be sure to use the save function to save the averaged matrices, then use load to retrieve them when you need them. Then you only have to do the loop calculation once for each data set.
  댓글 수: 4
Marc
Marc 2014년 5월 27일
No, there's nothing wrong with curiosity. But you should be passionately curious to do science. However, you shouldn't be too curious because then you will write a whole lot of interesting but very unnecessary stuff into your thesis ;)
Anyways, good to know that. There's nothing wrong with your signal processing perspective, your approach is definitely more correct so I will take it. My background is also sort of signal processing (electrical engineering, automation and information systems) but today I am doing more economics, feasibility studies and stuff like that ... so my Matlab times are a bit back in time ;)
Cheers!
Star Strider
Star Strider 2014년 5월 27일
I completely agree about being passionately curious about science. I pity those who are not. Being too curious is fine. Being selective and focused about your writing is also.
My applicable background here is in biomedical engineering (largely electrical), statistics and biomedical signal processing. So I’m sensitive about filters that aren’t designed for a specific purpose. They can do unkind things to one’s data.
Have fun!

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Marc
Marc 2014년 5월 25일
A lot of discussion going on here :D So, does my code work as expected or do I see things where there are no?
  댓글 수: 1
Star Strider
Star Strider 2014년 5월 25일
I believe you are seeing ‘aliasing’. I don’t use moving average filters because they have undesirable frequency characteristics. If you want to filter out noise, I suggest a low pass filter.
You will likely need to do a Fourier transform on your data (if you have not already) to see its frequency content and make the appropriate filter choices. The Signal Processing Toolbox makes filter design and implementation quite easy.

댓글을 달려면 로그인하십시오.


Marc
Marc 2014년 5월 25일
So, you mean I didn't compute the 1min average!? All I want to do is to produce one minute averages to smooth the data. That can't be too hard, can it?
  댓글 수: 2
Star Strider
Star Strider 2014년 5월 25일
If you want the average over each minute, the moving average filter is not your optimal choice. It takes the mean over samples 1:30 then 2:31, 3:32, etc. If that is what you want, use the moving average filter in spite of its suboptimal passband characteristics. (I don’t have the Financial Toolbox, so I can only simulate what I believe the movavg function does. It is not well-documented from a signal processing perspective.)
I infer by a 1 min average ’ that you want the average of the first minute (samples 1:30), the second minute (samples 31:60), etc. The documentation for mean has all the information you need to do that.
Marc
Marc 2014년 5월 26일
Thank you star strider. I agree with you, that I want the average minute by minute. I also agree with you, that I am not sure if movavg does what I want.
I know that I can use the function mean in a for loop to compute the average window by window. However, my matrices are quite long, around 119.000 rows, and I wanted to avoid using loops because I expect the computation to be quite long (ten matrices with a maximum of 43 vectors and a length of about 119.000...). That is why I wanted to use a built in function :)
Anyways, I don't see anything in the documentation of the function mean if I can use it to compute the average window by window without using a loop. Is that because there is only the loop-way or am I blind ;)?
Thanks in advance.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Statistics and Linear Algebra에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by