Aarish Ramesh
Aarish Ramesh

Reputation: 7033

Computing moving average for a specific last n duration in java

I have encountered an use case wherein i am supposed to calculate moving average for a specific duration, say for last n days. I know this can be accomplished easily if i store all the past data that i can subtract the contribution corresponding to the previous days. But how do i effectively compute it only storing the previous days average without the previous data.

Below is what I want to accomplish

Say for example I have 5 days of data like 2, 8, 5, 2, 5 and its average is 4.4 Now If have a eighth day's data to be 10 then running average should be calculated leaving out the elements first 3 elements 2, 8 and 5 and thus average will be 3.2
Currently I employ an approach of determining average contribution corresponding to a day and subtract it with total average which i feel is inaccurate

 Formula = (avg for past n days) +  (today's count/n) - 
-(no_of_days from the last computed day * (avg for past n days)/n)

So can someone please suggest me an effective implementation/computation formula for achieving this?

Upvotes: 1

Views: 1679

Answers (2)

Stephen C
Stephen C

Reputation: 718926

But how do i effectively compute it only storing the previous days average without the previous data.

You can't. A simple rolling average or moving average requires you to remember all values in the interval. There is no (useful)1 formula that allows you to do otherwise.

However that's not the end of it. There are other rolling-average measures that don't require you to store all of the values; e.g. "weighted moving average", "cumulative moving average", "exponential moving average" and so on. The Wikipedia on Moving Averages gives a good overview, describing the properties of the various measures and providing formulae.

I suggest you read the page, and then make your choice. Implementing any one of the rolling average measures in Java should be a simple programming task.


1 - You could invent a useless one ... that relied on storing N other values derived from the original ones. But I don't think that will help.

Upvotes: 3

Tim B
Tim B

Reputation: 41188

What you are asking for is not possible, you've thrown away the data so cannot magically get it back.

You could calculate a moving average simply by doing:

averageSoFar = (averageSoFar+scoreForToday) / 2

That heavily weighs it towards today though so what you probably want is a ratio for how much to take from today and how much from the average so far. For example if you want a 10 day moving average then a starting point for that will be 0.1

averageSoFar = averageSoFar *(1-weightingFactor)+scoreForToday*weightingFactor

Really you should either keep the data or look up proper algorithms for exactly what you need though.

Upvotes: 1

Related Questions