简体   繁体   English

如何计算C#数组列表的滚动平均值?

[英]How to calculate the rolling average of a C# array list?

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 我原始的数组列表称为numlist,它包含1到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 第一平均值=(1 + 2 + 3 + 4)/ 4

second average = (2+3+4+5)/4 第二平均值=(2 + 3 + 4 + 5)/ 4

third average = (3+4+5+6)/4 第三平均值=(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? 我该如何实现?

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);
}

You can use LINQ like this: 您可以这样使用LINQ:

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. 在您的示例中,它从i = 0i = 5 ,并从索引i开始的列表中取出4个元素,并计算它们的平均值。

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: 说明文件:

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 : avelist将类似于以下@ @执行结束:

{2.5, 3.5, 4.5, 5.5, 6.5, 7.5}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM