Reputation: 477
Say I've got a list:
List<int> numbers = new List<int>();
and I'm trying to get the "running averages" of it. (Sorry, I don't really know how to call it).
For instance:
The first item in this list is 5
, the average of 5
is 5
, so the first average is 5
.
The second item in this list is 7
, the average of 5 and 7
is 6
, so the second average is 6
.
The third item in this list is 10
, the average of 5, 7 and 10
is 7.3
, so the third average is 7.3
And so on.
Those first average, second average etc are the averages I'm trying to get. How would I go about doing this? I've been searching the internet but honestly I'm not quite sure what I should be looking for. :(
Upvotes: 2
Views: 1703
Reputation: 548
You need the "Running Average", not the average from the start over all items I assume?
The running average needs a number to tell how far back to look and one to tell how far forward to look.
This will give you the running average:
public List<double> GetRunningAverage(List<double> SourceList, int ItemsBefore, int ItemsAfter)
{
List<double> TargetList = new List<double>() { };
// Only makes sense if the list is > 1 of course
if (SourceList.Count > 1)
{
for (int i = 0; i < SourceList.Count; i++)
{
int LookBack =
(ItemsBefore > i ? i : ItemsBefore);
int LookForward =
(ItemsAfter < SourceList.Count - i
? ItemsAfter : SourceList.Count - i);
TargetList.Add(SourceList.GetRange(i - LookBack, LookBack + LookForward).Average());
}
}
else
{
TargetList.AddRange(SourceList);
}
return TargetList;
}
You can then use it like this:
List<double> FullList = GetRunningAverage(
new List<double>() { 100, 5, 5, 6, 23, 10, 56, 32, 54, 1, 3, 85, 65, 49, 22, 65, 32, 5, 2, 4, 5, 89, 110, 55, 6, 56, 57 },
3, // Looking back 3 items
3); // Looking forward 3 items
Upvotes: 0
Reputation: 38875
The lists
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
test data
numbers.AddRange(new int[]{5, 7, 10});
// get average of current List
averages.Add(numbers.Average());
Such a list of averages all by itself usually doesnt mean much without some other data like number of elements, duration of time or something to qualify it.
This method is better suited when the moving average is not one for one with the values. For instance, the app stores values. Then periodically, say once a minute, the average is calculated and stored.
Upvotes: 2
Reputation: 2673
try this:
string st = Console.ReadLine();
string[] strs = st.Split(' ');
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
for (int i = 0; i < strs.Length; i++)
{
numbers.Add(int.Parse(strs[i]));
averages.Add(numbers.Average());
}
this will read the numbers from the standard input, the numbers are separated by space in input.
Upvotes: 5
Reputation: 101691
You can try something like this:
var averages = Enumerable.Range(1, numbers.Count)
.Select(x => numbers.Take(x).Average())
.ToList();
This will generate a sequence from 1
to numbers.Count
. Then using Take
it will get X
element at each time (you can think X
as an index, only difference is it starts from 1
and increases one by one up to the numbers.Count
) starting from the first element then get their average
.Put them into a list.
Upvotes: 4