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

5

我想计算一个数组列表中每四个值的滚动平均值,并将这些值添加到另一个数组列表中。我的原始数组列表称为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);

当计算滚动平均值时,应按以下方式进行:
第一个平均值 = (1+2+3+4)/4
第二个平均值 = (2+3+4+5)/4
第三个平均值 = (3+4+5+6)/4
以此类推
因此,第二个数组列表...(未完待续)
List<double> avelist = new List<double>();

应该包含这些值

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

我该如何实现这个目标?

你已经尝试过什么了? - yaakov
3个回答

6

如果你关心性能,可以使用队列并只处理来源中的每个项目一次:

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

呼叫:

foreach (double a in RollingAverages(new List<int> {1,2,3,4,5,6,7,8,9}, 4)) {
    Console.WriteLine(a);
}

5

您可以像这样使用LINQ:

List<double> averages = Enumerable.Range(0, numlist.Count - 3).
                              Select(i => numlist.Skip(i).Take(4).Average()).
                              ToList();

在你的例子中,这个循环从i = 0i = 5,并且从以i为索引的列表中取出4个元素,并计算它们的平均值。
你可以像这样输出结果:
Console.WriteLine(string.Join(" ", averages));

一个带有变量“width”的滚动平均方法可能如下所示:
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:


我尝试过这个,但是当我使用Console.WriteLine(averages)在控制台上打印它时,它只会打印出:System.Collections.Generic.List`1[System.Double]。 - coder
当然是程序员,因为 Console.WriteLine 调用了 List<double> 上的 ToString() 方法来输出类型。我已经更新了我的答案,提供了一种正确的输出方式。 - René Vogt
numlist.Count-3 是什么意思? - coder
@coder Range 的第二个参数是您想在该范围内拥有的元素数量。在这个例子中,您需要6个(= 9-3)元素,因为您想要6个平均值(1-4、2-5、3-6、4-7、5-8和6-9)。numList.Count 是您原始列表中的元素数量。 - René Vogt

1
以下代码将帮助您:

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 将如下所示:
{2.5, 3.5, 4.5, 5.5, 6.5, 7.5}

在第一个数组列表中,我正在尝试获取在avelist中的值:2.5,3.5等,这就是我想要得到的输出。因此,这会找到平均值的滚动平均值吗? - coder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接