如何解决按两列分组并根据其中一列计算累计值
请考虑以下列表:
List<Data> lst = new List<Data>
{
new Data() { Id = 1,Val1 = 100 },new Data() { Id = 1,Val1 = 200 },Val1 = 300 },new Data() { Id = 2,new Data() { Id = 3,};
然后是此代码:
decimal Cumulative_Probability = 0;
var Result1 = (lst.OrderBy(o => o.Id).GroupBy(x => new { x.Val1 })
.Select(y => new
{
y.Key.Val1,Probability = (Convert.ToDecimal(y.Count()) / lst.Count),Cumulative_Probability = (Cumulative_Probability =
Cumulative_Probability +
(Convert.ToDecimal(y.Count()) / lst.Count))
})).OrderBy(o => o.Val1).ToList();
此代码可以正常工作,并且Cumulative_Probability
的计算正确。
现在请考虑以下代码:
decimal Cumulative_Probability2 = 0;
var Result2 = (lst.OrderBy(o => o.Id).GroupBy(x => new { x.Id,x.Val1 })
.Select(y => new
{
y.Key.Id,y.Key.Val1,Probability = (Convert.ToDecimal(y.Count())
/ lst.Where(o => o.Id == y.Key.Id).Count()),Cumulative_Probability = (Cumulative_Probability2 =
Cumulative_Probability2 +
(Convert.ToDecimal(y.Count()) /
lst.Where(o => o.Id == y.Key.Id).Count()))
})).OrderBy(o => o.Id).ThenBy(o => o.Val1).ToList();
此代码生成以下结果:
您可以看到在每个组中正确计算出Probability
,但没有Cumulative_Probability
。我想计算每个 Id 组中的Cumulative_Probability
(组记录首先按Id
,然后按Val1
),并且Cumulative_Probability2
不在每个组中重置。如何计算每个组中的Cumulative_Probability
?
谢谢
编辑1)
我想要这个结果:
Id Val1 Probability Cumulative_Probability
-------------------------------------------------------------------------
1 100 0.16 0.16
1 200 0.66 0.82
1 300 0.16 0.98
2 100 0.33 0.33
2 200 0.66 0.66
...
解决方法
我设法借助扩展方法来做到这一点,该方法累积了累积概率以及一些嵌套的next-redux-wrapper
。我敢肯定一定有一种更简单的方法,但是我正在努力寻找答案。
扩展名是:
GroupBy
完成的代码如下:
public static class EnumerableExtensions
{
public static IEnumerable<TResult> Accumulate<TSource,TAccumulate,TResult>(
this IEnumerable<TSource> source,TAccumulate seed,Func<TAccumulate,TSource,(TAccumulate,TResult)> accumulator)
{
var acc = seed;
foreach(TSource value in source)
{
var (newSeed,newSource) = accumulator.Invoke(acc,value);
yield return newSource;
acc = newSeed;
}
}
}
实时示例:https://dotnetfiddle.net/dvW1qo
,此代码有效:
var Result2 = (from a in lst.OrderBy(o => o.Id)
group a by new { a.Id,a.Val1 } into grp
select new
{
grp.Key.Id,grp.Key.Val1,Probability = (Convert.ToDecimal(grp.Count()) / lst.Where(o => o.Id == grp.Key.Id).Count()),Cumulative_Probability = (from b in lst.Where(o => o.Id == grp.Key.Id && o.Val1 <= grp.Key.Val1)
group b by new { b.Val1 } into grp2
select new
{
Probability2 = (Convert.ToDecimal(grp2.Count()) / lst.Where(o => o.Id == grp.Key.Id).Count())
}).Sum(o => o.Probability2)
}).OrderBy(o => o.Id).ThenBy(o => o.Val1).ToList();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。