我有一个包含多个组的数据集。
我必须计算两件事:
每组数据的平均值 - 我用以下代码完成:
var results = from res in dt.AsEnumerable()
group res by res.Field<string>(key)
into grp
orderby Convert.ToInt32(grp.Key)
select new
{
date = grp.Key,
sum = grp.Average(r => Convert.ToDouble(r.Field<string> (average)))
};
我还需要计算每个组的值的标准差,因此对于每个组,我需要创建一个数组或每个组的单个结果列表。我怎么能用LINQ做到这一点?
感谢。
编辑:我很感激我的问题,我有点模糊;我知道如何计算标准偏差,我想知道如何提取每个组的值列表(如上所述)以允许执行计算。感谢。答案 0 :(得分:1)
这是关于计算标准偏差的问题/答案: Standard Deviation in LINQ
对于项目列表,只需执行items = grp.ToList()
或grp.Select(c => c.Field...).ToList()
var results = from res in dt.AsEnumerable()
group res by res.Field<string>(key)
into grp
orderby Convert.ToInt32(grp.Key)
select new
{
date = grp.Key,
sum = grp.Average(r => Convert.ToDouble(r.Field<string>(average))),
items = grp.ToList(),
sd = CalcSD(grp.Select(c => Convert.ToDouble(r.Field<string>(average))))
};
答案 1 :(得分:1)
的Darren,
快速SO linq(双关语意图!!)让你继续前进,直到得到进一步的答案:
Standard deviation of generic list?
希望这会有所帮助
[edit] - 根据上面的SO链接,您可以修改并尝试(在静态类中):
public static double StdDev(this IEnumerable<double> values)
{
double ret = 0;
if (values.Count() > 0)
{
//Compute the Average
double avg = values.Average();
//Perform the Sum of (value-avg)_2_2
double sum = values.Sum(d => Math.Pow(d - avg, 2));
//Put it all together
ret = Math.Sqrt((sum) / (values.Count()-1));
}
return ret;
}
再加上一点覆盖(我已经处理过但后来改变了看这个链接http://help.syncfusion.com/ug_84/User%20Interface/WPF/Grid/default.htm?turl=Documents%2Fcustomsummaries.htm):
public static double StdDev<T>(this IEnumerable<T> values, Func<T, double?> selector)
{
double ret = 0;
var count = values.Count();
if (count > 0)
{
// Compute the Average
double? avg = values.Average(selector);
// Perform the Sum of (value-avg)^2
double sum = values.Select(selector).Sum(d =>
{
if (d.HasValue)
{
return Math.Pow(d.Value - avg.Value, 2);
}
return 0.0;
});
// Put it all together
ret = Math.Sqrt((sum) / (count - 1));
}
return ret;
}
然后简单地申请:
var results = from res in dt.AsEnumerable()
group res by res.Field<string>(key)
into grp
orderby Convert.ToInt32(grp.Key)
select new
{
date = grp.Key,
sum = grp.Average(r => Convert.ToDouble(r.Field<string>(average))),
stdDev = gp.Select(s => Convert.ToDouble(s.Field<string>(average))).StdDev(),
// alternative override - note no need to convert
stdDev2 = gp.StdDev(s => s.Field<string>(average))
};
没有经过测试,所以可能不会马上工作,但理论就在那里。