如何计算 C# 数组列表的滚动平均值?
How to calculate the rolling average of a C# array list?
我正在尝试计算数组列表中每四个值的滚动平均值,并将这些值添加到单独的数组列表中。我的原始数组列表称为 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}
我怎样才能做到这一点?
您可以像这样使用 LINQ:
List<double> averages = Enumerable.Range(0, numlist.Count - 3).
Select(i => numlist.Skip(i).Take(4).Average()).
ToList();
在您的示例中,这从 i = 0
到 i = 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();
}
文档:
以下代码可以帮到您:
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}
如果您关心性能,可以使用队列并只处理源中的每个项目一次:
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);
}
我正在尝试计算数组列表中每四个值的滚动平均值,并将这些值添加到单独的数组列表中。我的原始数组列表称为 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}
我怎样才能做到这一点?
您可以像这样使用 LINQ:
List<double> averages = Enumerable.Range(0, numlist.Count - 3).
Select(i => numlist.Skip(i).Take(4).Average()).
ToList();
在您的示例中,这从 i = 0
到 i = 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();
}
文档:
以下代码可以帮到您:
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}
如果您关心性能,可以使用队列并只处理源中的每个项目一次:
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);
}