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

cod*_*der 4 c# arraylist moving-average

我正在尝试计算数组列表中每四个值的滚动平均值,并将这些值添加到单独的数组列表中。我的原始数组列表称为 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);
Run Code Online (Sandbox Code Playgroud)

当它计算滚动平均值时,它应该以如下方式进行:

第一平均值 = (1+2+3+4)/4

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

第三平均值 = (3+4+5+6)/4

等等

所以第二个数组列表,

List<double> avelist = new List<double>();
Run Code Online (Sandbox Code Playgroud)

应该包含这些值

{2.5, 3.5, 4.5, 5.5, 6.5, 7.5}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Ren*_*ogt 5

您可以像这样使用 LINQ:

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

在您的示例中,这从i = 0i = 5并从列表中从索引开始获取 4 个元素i并计算它们的平均值。

您可以像这样输出结果:

Console.WriteLine(string.Join(" ", averages));
Run Code Online (Sandbox Code Playgroud)

具有可变“宽度”的滚动平均值的方法可能如下所示:

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();
}
Run Code Online (Sandbox Code Playgroud)

文档:


Den*_*s_E 5

如果您关心性能,您可以使用 Queue 并且只处理源中的每个项目一次:

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;
}
Run Code Online (Sandbox Code Playgroud)

称呼:

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