问题
I'm trying to calculate the rolling averages of every four values in an array list and add those values to a separate array list. My original array list is called numlist and it contains values from 1 to 9
List<int> numlist = new List<int>();
numlist.Add(1);
numlist.Add(2);
numlist.Add(3);
numlist.Add(4);
numlist.Add(5);
numlist.Add(6);
numlist.Add(7);
numlist.Add(8);
numlist.Add(9);
When it calculates rolling averages, it should do it in an way like this:
first average = (1+2+3+4)/4
second average = (2+3+4+5)/4
third average = (3+4+5+6)/4
and so on
so the second array list,
List<double> avelist = new List<double>();
should contain these values
{2.5, 3.5, 4.5, 5.5, 6.5, 7.5}
How can I achieve this?
回答1:
You can use LINQ like this:
List<double> averages = Enumerable.Range(0, numlist.Count - 3).
Select(i => numlist.Skip(i).Take(4).Average()).
ToList();
In your example, this goes from i = 0
to i = 5
and takes 4 elements from the list starting at index i
and calculates their average.
You can output the result like that:
Console.WriteLine(string.Join(" ", averages));
A method with a variable "width" for the rolling average could look like:
public List<double> RollingAverage(List<int> source, int width)
{
return Enumerable.Range(0, 1 + numlist.Count - width).
Select(i => numlist.Skip(i).Take(width).Average()).
ToList();
}
Documentation:
- Enumerable.Range
- Enumerable.Select
- Enumerable.Skip
- Enumerable.Take
- Enumerable.Average
回答2:
If you care about performance, you can use a Queue and process each item in the source only once:
IEnumerable<double> RollingAverages(IEnumerable<int> numbers, int length) {
var queue = new Queue<int>(length);
double sum = 0;
foreach (int i in numbers) {
if (queue.Count == length) {
yield return sum / length;
sum -= queue.Dequeue();
}
sum += i;
queue.Enqueue(i);
}
yield return sum / length;
}
Call:
foreach (double a in RollingAverages(new List<int> {1,2,3,4,5,6,7,8,9}, 4)) {
Console.WriteLine(a);
}
回答3:
The following code will help you:
List<int> numlist = Enumerable.Range(1, 10).ToList();// generating list
List<double> avelist = new List<double>();
Dictionary<int, double> rollingAvg = new Dictionary<int, double>();
int limit = 4, i = 0;
while (limit + i <= numlist.Count)
{
avelist.Add(numlist.Skip(i).Take(limit).Average());
i++;
}
avelist will be like the following @ the End of the execution :
{2.5, 3.5, 4.5, 5.5, 6.5, 7.5}
来源:https://stackoverflow.com/questions/36862081/how-to-calculate-the-rolling-average-of-a-c-sharp-array-list