用linq计算平均值,不分组
本文关键字:平均值 linq 计算 | 更新日期: 2023-09-27 18:17:17
我有一个数据表,它包含几个列。我想用linq计算这些的平均值,不分组:我试过了:
dtPointCollFb.GroupBy(r => 1).Select(r => new
{
Plus100 = r.Average(item => item.PLUS100),
Plus50 = r.Average(item => item.PLUS50),
Plus10 = r.Average(item => item.PLUS10),
Plus5 = r.Average(item => item.PLUS5),
Plus1 = r.Average(item => item.PLUS1),
NULLA = r.Average(item => item.NULLA)
}).ToList()
这工作完美,当我计算Sum,但平均产生第一个记录值,而不是所有记录的平均值。我认为这是不必要的:. groupby (r => 1),因为我是用常量分组。
但是如果没有这个,我就不能对整个查询使用平均值,而且只能对一列使用平均值:
dtPointCollFb.Average(r => r.PLUS100)
那么有人能提出一个简单的最佳实践解决方案吗?如果可能的话,使用方法语法,而不是查询。
我想要这样的东西:
dtPointCollFb.GroupBy(r => 0).Select(r => new
{
Plus100 = r.Sum(item => item.PLUS100) / dtPointCollFb.Rows.Count,
Plus50 = r.Sum(item => item.PLUS50) / dtPointCollFb.Rows.Count,
Plus10 = r.Sum(item => item.PLUS10) / dtPointCollFb.Rows.Count,
Plus5 = r.Sum(item => item.PLUS5) / dtPointCollFb.Rows.Count,
Plus1 = r.Sum(item => item.PLUS1) / dtPointCollFb.Rows.Count,
NULLA = r.Sum(item => item.NULLA) / dtPointCollFb.Rows.Count
}).ToList()
,但更简单,更干净的方式。
可枚举。Average计算一个数列的平均值。因此,您需要为需要的每个平均值投影(即选择)一列。
dtPointCollFb.Select(r => r.PLUS100).Average()
或
dtPointCollFb.Average(r => r.PLUS100)
GroupBy构建一个列表的列表。在这种情况下,(外部)列表只有一个元素。(因为您对原始列表中的所有元素任意使用相同的键)
所以你上面的内容可以很容易地写成:
var averages = new
{
Plus100 = dtPointCollFb.Average(item => item.PLUS100),
Plus50 = dtPointCollFb.Average(item => item.PLUS50),
Plus10 = dtPointCollFb.Average(item => item.PLUS10),
Plus5 = dtPointCollFb.Average(item => item.PLUS5),
Plus1 = dtPointCollFb.Average(item => item.PLUS1),
NULLA = dtPointCollFb.Average(item => item.NULLA)
};
做更多的事情需要自定义扩展函数(扩展IEnumerable<DataTableClass>
)。
如果像Christopher建议的那样,您想要使用扩展,您可以使用Aggregate
方法。
给定类
public class DataPoint
{
public double Plus100 { get; set; }
public double Plus50 { get; set; }
public double Plus10 { get; set; }
public double Plus5 { get; set; }
public double Plus1 { get; set; }
public double NULLA { get; set; }
}
平均函数看起来像这样(手动计数避免通过集合进行多个枚举):
public static DataPoint Average(this IEnumerable<DataPoint> dataPoints)
{
var count = 0;
var totals = dataPoints.Aggregate((lhs, rhs) =>
{
++count;
return new DataPoint
{
Plus100 = lhs.Plus100 + rhs.Plus100,
Plus50 = lhs.Plus50 + rhs.Plus50,
Plus10 = lhs.Plus10 + rhs.Plus10,
Plus5 = lhs.Plus5 + rhs.Plus5,
Plus1 = lhs.Plus1 + rhs.Plus1,
NULLA = lhs.NULLA + rhs.NULLA
};
});
return new DataPoint
{
Plus100 = totals.Plus100 / count,
Plus50 = totals.Plus50 / count,
Plus10 = totals.Plus10 / count,
Plus5 = totals.Plus5 / count,
Plus1 = totals.Plus1 / count,
NULLA = totals.NULLA / count
};
}
这个方法的优点是它只遍历一次集合。如果您有一个大型数据集,这将节省计算能力。如果你有更少的数据点,我会使用Christopher的方法。