获取 "running average" 个列表
get "running average" of a list
假设我有一个列表:
List<int> numbers = new List<int>();
我正在尝试获取它的 "running averages"。 (抱歉,我真的不知道怎么称呼它)。
例如:
此列表中的第一项是 5
,5
的平均值是 5
,因此第一个平均值是 5
。
此列表中的第二项是 7
,5 and 7
的平均值是 6
,因此第二个平均值是 6
。
这个列表中的第三项是10
,5, 7 and 10
的平均值是7.3
,所以第三个平均值是7.3
等等。
那些第一平均数、第二平均数等是我试图获得的平均数。我该怎么做呢?我一直在网上搜索,但老实说我不太确定我应该寻找什么。 :(
您可以尝试这样的操作:
var averages = Enumerable.Range(1, numbers.Count)
.Select(x => numbers.Take(x).Average())
.ToList();
这将生成一个从 1
到 numbers.Count
的序列。然后使用 Take
每次都会得到 X
个元素(你可以把 X
看作一个索引,唯一不同的是它从 1
开始,一个一个地增加到numbers.Count
) 从第一个元素开始,然后获取它们的 average
。将它们放入列表中。
试试这个:
string st = Console.ReadLine();
string[] strs = st.Split(' ');
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
for (int i = 0; i < strs.Length; i++)
{
numbers.Add(int.Parse(strs[i]));
averages.Add(numbers.Average());
}
这将从标准输入中读取数字,数字在输入中由 space 分隔。
名单
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
测试数据
numbers.AddRange(new int[]{5, 7, 10});
// get average of current List
averages.Add(numbers.Average());
如果没有一些其他数据(例如元素的数量、持续时间或其他限定条件),这样的平均值列表本身通常意义不大。
当移动平均线与值不是一对一时,此方法更适用。例如,应用程序存储值。然后周期性地,比如每分钟一次,计算并存储平均值。
您需要“运行 平均值”,而不是我假设的所有项目从一开始的平均值?
运行 平均值需要一个数字表示向后看多远,一个表示向前看多远。
这将为您提供 运行 平均值:
public List<double> GetRunningAverage(List<double> SourceList, int ItemsBefore, int ItemsAfter)
{
List<double> TargetList = new List<double>() { };
// Only makes sense if the list is > 1 of course
if (SourceList.Count > 1)
{
for (int i = 0; i < SourceList.Count; i++)
{
int LookBack =
(ItemsBefore > i ? i : ItemsBefore);
int LookForward =
(ItemsAfter < SourceList.Count - i
? ItemsAfter : SourceList.Count - i);
TargetList.Add(SourceList.GetRange(i - LookBack, LookBack + LookForward).Average());
}
}
else
{
TargetList.AddRange(SourceList);
}
return TargetList;
}
然后你可以像这样使用它:
List<double> FullList = GetRunningAverage(
new List<double>() { 100, 5, 5, 6, 23, 10, 56, 32, 54, 1, 3, 85, 65, 49, 22, 65, 32, 5, 2, 4, 5, 89, 110, 55, 6, 56, 57 },
3, // Looking back 3 items
3); // Looking forward 3 items
假设我有一个列表:
List<int> numbers = new List<int>();
我正在尝试获取它的 "running averages"。 (抱歉,我真的不知道怎么称呼它)。
例如:
此列表中的第一项是 5
,5
的平均值是 5
,因此第一个平均值是 5
。
此列表中的第二项是 7
,5 and 7
的平均值是 6
,因此第二个平均值是 6
。
这个列表中的第三项是10
,5, 7 and 10
的平均值是7.3
,所以第三个平均值是7.3
等等。
那些第一平均数、第二平均数等是我试图获得的平均数。我该怎么做呢?我一直在网上搜索,但老实说我不太确定我应该寻找什么。 :(
您可以尝试这样的操作:
var averages = Enumerable.Range(1, numbers.Count)
.Select(x => numbers.Take(x).Average())
.ToList();
这将生成一个从 1
到 numbers.Count
的序列。然后使用 Take
每次都会得到 X
个元素(你可以把 X
看作一个索引,唯一不同的是它从 1
开始,一个一个地增加到numbers.Count
) 从第一个元素开始,然后获取它们的 average
。将它们放入列表中。
试试这个:
string st = Console.ReadLine();
string[] strs = st.Split(' ');
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
for (int i = 0; i < strs.Length; i++)
{
numbers.Add(int.Parse(strs[i]));
averages.Add(numbers.Average());
}
这将从标准输入中读取数字,数字在输入中由 space 分隔。
名单
List<int> numbers = new List<int>();
List<double> averages = new List<double>();
测试数据
numbers.AddRange(new int[]{5, 7, 10});
// get average of current List
averages.Add(numbers.Average());
如果没有一些其他数据(例如元素的数量、持续时间或其他限定条件),这样的平均值列表本身通常意义不大。
当移动平均线与值不是一对一时,此方法更适用。例如,应用程序存储值。然后周期性地,比如每分钟一次,计算并存储平均值。
您需要“运行 平均值”,而不是我假设的所有项目从一开始的平均值?
运行 平均值需要一个数字表示向后看多远,一个表示向前看多远。
这将为您提供 运行 平均值:
public List<double> GetRunningAverage(List<double> SourceList, int ItemsBefore, int ItemsAfter)
{
List<double> TargetList = new List<double>() { };
// Only makes sense if the list is > 1 of course
if (SourceList.Count > 1)
{
for (int i = 0; i < SourceList.Count; i++)
{
int LookBack =
(ItemsBefore > i ? i : ItemsBefore);
int LookForward =
(ItemsAfter < SourceList.Count - i
? ItemsAfter : SourceList.Count - i);
TargetList.Add(SourceList.GetRange(i - LookBack, LookBack + LookForward).Average());
}
}
else
{
TargetList.AddRange(SourceList);
}
return TargetList;
}
然后你可以像这样使用它:
List<double> FullList = GetRunningAverage(
new List<double>() { 100, 5, 5, 6, 23, 10, 56, 32, 54, 1, 3, 85, 65, 49, 22, 65, 32, 5, 2, 4, 5, 89, 110, 55, 6, 56, 57 },
3, // Looking back 3 items
3); // Looking forward 3 items