如何在linq中对不同的分组执行多个独立的聚合?
例如,我有一个表:
UNO YOS Ranking Score
123456 1 42 17
645123 3 84 20我想对分组和未分组的数据执行一组聚合,如下所示:
var grouped = table.GroupBy(x => x.score )
.Select(x => new
{
Score = x.Key.ToString(),
OverallAverageRank = x.Average(y => y.Ranking),
Year1RankAvg = x.Where(y => y.YOS == 1).Average(y => y.Ranking),
Year2RankAvg = x.Where(y => y.YOS == 2).Average(y => y.Ranking)
//...etc
});我还想在相同的切片和整集数据上执行不同的聚合(标准差)。
我不知道如何同时对YOS进行分组和不分组,虽然这样编译得很好,但当涉及到运行时时,如果有任何YOS平均值在,我会得到"Sequence contains no element“。
发布于 2019-06-21 02:01:07
与任何编程一样,当您有一系列相似的项时,请使用集合。在本例中,我将其保留为IEnumerable,但如果需要,您可以将其设置为List或YOS的Dictionary。
var ans = table.GroupBy(t => t.Score)
.Select(tg => new {
Score = tg.Key,
OverallAverageRank = tg.Average(t => t.Ranking),
YearRankAvgs = tg.GroupBy(t => t.YOS).Select(tyg => new { YOS = tyg.Key, RankAvg = tyg.Average(t => t.Ranking) })
});如果您需要填写从1到最大(或其他一些数字)的年份范围,您可以修改答案:
var ans2 = ans.Select(soryr => new {
soryr.Score,
soryr.OverallAverageRank,
YearRankDict = soryr.YearRankAvgs.ToDictionary(yr => yr.YOS),
YearMax = soryr.YearRankAvgs.Max(yr => yr.YOS)
})
.Select(soryr => new {
Score = soryr.Score,
OverAverageRank = soryr.OverallAverageRank,
YearRankAvgs = Enumerable.Range(1, soryr.YearMax).Select(yos => soryr.YearRankDict.ContainsKey(yos) ? soryr.YearRankDict[yos] : new { YOS = yos, RankAvg = 0.0 }).ToList()
});如果您愿意,可以修改原始ans以将RankAvg作为double?返回,并在添加缺少的年份时将null替换为0.0。
https://stackoverflow.com/questions/56582715
复制相似问题