按范围对数据进行分组以生成直方图

时间:2014-11-26 20:49:32

标签: c# linq

我试图在C#中制作终身价值直方图。

我想将数据分组到10美元的存储桶中。我试图找到一种方法,我不必明确定义每个桶。

输出将是这样的:

Range : Count  
0-10 : 23  
10-20 : 40  
20-30 : 43  

等...

我也有会员表;让我说他有两个领域。

int Id
Decimal LifeTimeValue

有没有办法在LINQ中执行此操作,并不要求我明确定义每个存储桶?

这是我迄今为止在SQL中所做的工作。我可以轻松地将其移植到LINQ中,但这是一个糟糕的方法,因为我必须为每个存储桶复制一个when子句。

select
case when LifeTimeValue >= 0 and LifeTimeValue < 10    then '  0 - 10'
           when LifeTimeValue > 10 and LifeTimeValue <= 20   then ' 10+ - 20'
           when LifeTimeValue > 20 and LifeTimeValue <= 30  then ' 20+ - 30'
           else 'over 30'
end As PriceRange,
count(LifeTimeValue) as ItemTotal
from tblMember
group by 
case when LifeTimeValue >= 0 and LifeTimeValue < 10    then '  0 - 10'
           when LifeTimeValue > 10 and LifeTimeValue <= 20   then ' 10+ - 20'
           when LifeTimeValue > 20 and LifeTimeValue <= 30  then ' 20+ - 30'
           else 'over 30'
end;

2 个答案:

答案 0 :(得分:6)

创建直方图时,重要的是覆盖存储桶可能没有数据的情况。对于存储桶0的结果非常重要。

以桶顺序提供数据也是明智之举。

首先进行查找:

var lookup = context.Member.ToLookup(x => (int)x.LifeTimeValue / 10);

更改为int允许整数除法生成存储区。

现在我们需要找到数据的范围:

var smallest = lookup.Min(x => x.Key);
var largest = lookup.Max(x => x.Key);

现在查询很简单:

var query =
    from x in Enumerable
        .Range(smallest, largest - smallest + 1)
    select new
    {
        Range = String.Format("{0}-{1}", x * 10, (x + 1) * 10),
        Count = lookup[x].Count(),
    };

这是我创建的一些示例数据的结果:

histogram data

请注意,10-20范围的计数为0

答案 1 :(得分:5)

关键部分是:x.LifeTimeValue - (x.LifeTimeValue % 10)

var query = from x in context.Member
            group x by x.LifeTimeValue - (x.LifeTimeValue % 10) into x
            select new
            {
              Range = x.Key,
              Count = x.Count()
            }