You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#/Linq中基于IGrouping分组计数计算季度环比百分比变化

解答

完全可以利用Select方法的索引参数完成两项指标的环比百分比计算,但不能直接在你当前写的分组后连续Select逻辑里直接计算——因为单条Select执行时只能拿到当前遍历的分组对象,无法获取上一个季度的统计值,需要分两步实现:

  • 第一步先完成季度分组的基础计数,落地为内存中的有序列表
  • 第二步基于这个有序列表,用带索引的Select匹配上一期数据计算环比

环比计算规则说明

  • 第一条(索引为0)的季度数据无前置对比期,InvestigationsChange和BreachesChange均设为0
  • 环比百分比公式:(当期值 - 上期值) / 上期值 * 100
  • 增加除零容错:当上期指标值为0时,直接返回变化率0,避免运行时报错

完整实现代码

// 1. 按季度分组统计基础指标值,生成有序基础数据集
var quarterlyStats = Metrics
    .GroupBy(m => m.Quarter)
    .Select(g => new 
    {
        Quarter = g.Key,
        Investigations = g.Count(),
        // 直接给Count传筛选条件,比Where+Count少一次集合遍历,性能更优
        Breaches = g.Count(a => a.Breach == "Yes")
    })
    .ToList();

// 2. 基于有序数据集,通过索引取上一期数据计算环比
var result = quarterlyStats
    .Select((item, index) => new StatusCountDto
    {
        Quarter = item.Quarter,
        Investigations = item.Investigations,
        Breaches = item.Breaches,
        InvestigationsChange = index == 0
            ? 0
            : quarterlyStats[index - 1].Investigations == 0
                ? 0
                : (double)(item.Investigations - quarterlyStats[index - 1].Investigations) / quarterlyStats[index - 1].Investigations * 100,
        BreachesChange = index == 0
            ? 0
            : quarterlyStats[index - 1].Breaches == 0
                ? 0
                : (double)(item.Breaches - quarterlyStats[index - 1].Breaches) / quarterlyStats[index - 1].Breaches * 100
    })
    .ToList();

注意事项

  • 如果你需要的是小数形式的环比(比如0.15代表15%,而非15),删掉计算逻辑里的* 100即可
  • 该实现依赖你提到的「原始数据已按Quarter排序」的前提,LINQ to Objects中的GroupBy会保留原始分组的出现顺序,不需要额外再做排序
  • 如果你能确保业务上不会出现上期指标值为0的情况,可以去掉除零判断简化代码,但生产环境建议保留容错逻辑

内容的提问来源于stack exchange,提问作者Canolyb1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:06:28