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

C#实现月度平均能耗值计算的技术方案咨询

如何计算月度平均能耗值

我有一个包含DateEnergyValue类实例的列表,类定义如下:

public class DateEnergyValue 
{
   public DateOnly CollectedDate{ get; set; }
   public double Value { get; set; }
}

List<DateEnergyValue> DateEnergyValues = new List<DateEnergyValue>() { /* 数据填充 */ } 

需求是计算月度平均能耗值,计划步骤:

  • 找出所有数据的起止日期并计算年份跨度
  • 按月份分组计算平均能耗,同一月份多条数据取平均值

已实现起止日期和年份数的计算:

var startDate = DateEnergyValues.Min(a => a.CollectedDate);
var endDate = DateEnergyValues.Max(r=>r.CollectedDate);
// 修正:原代码startDate - endDate会得到负数,应该用endDate减startDate
TimeSpan TS = endDate - startDate;
double Years = TS.TotalDays / 365.25; 

但不清楚后续分组计算逻辑,以下是示例数据:

采集日期(月/日/年)能耗值
5/1/20092400
6/1/20092400
7/1/20092400
8/1/20097315.8
9/1/20095140.3
10/1/20091557.8
11/1/20091557.8
12/1/2009369.7
1/1/2010369.7
2/1/2010144.8
3/1/2010437.2
4/1/2010804.1
5/1/2010965.1
6/1/20101131
7/1/20101179.4
8/1/20101170.8
9/1/2010993.6
10/1/2010714.9
11/1/2010244.3
12/1/2010126.8
1/1/2011122.1
2/1/2011114.6
3/1/2011185.2
4/1/2011441.9
5/1/20111494.9
6/1/20111009.9
7/1/20113051.3
8/1/20113229.7
9/1/2011996
10/1/20113328.7
11/1/2011870.1
12/1/20111051.8
4/1/2011481000
5/1/2011446000
6/1/2011608000
7/1/2011323000
8/1/2011478000
9/1/2011452000
10/1/2011505000
11/1/2011438000
12/1/2011456654

实现思路与代码

1. 基础分组计算(仅计算有数据的月份)

使用LINQ的GroupBy按年份+月份分组,然后对每组计算平均值:

// 按年和月分组,计算每组的平均值
var monthlyAverages = DateEnergyValues
    .GroupBy(item => new { item.CollectedDate.Year, item.CollectedDate.Month })
    .Select(group => new 
    {
        Year = group.Key.Year,
        Month = group.Key.Month,
        AverageValue = group.Average(item => item.Value)
    })
    .OrderBy(result => result.Year)
    .ThenBy(result => result.Month)
    .ToList();

这段代码会输出所有存在数据的月份的平均能耗,并且按时间顺序排序。

2. 补全起止日期范围内的所有月份(包括无数据的月份)

如果需要显示起止日期之间的所有月份(即使该月没有数据,平均值设为0或null),可以先生成所有月份的序列,再和分组结果关联:

// 生成起止日期之间的所有月份
var allMonths = new List<DateOnly>();
var currentMonth = new DateOnly(startDate.Year, startDate.Month, 1);
while (currentMonth <= endDate)
{
    allMonths.Add(currentMonth);
    currentMonth = currentMonth.AddMonths(1);
}

// 关联分组数据,补全无数据月份的平均值
var completeMonthlyAverages = allMonths
    .Select(month => new
    {
        Year = month.Year,
        Month = month.Month,
        AverageValue = DateEnergyValues
            .Where(item => item.CollectedDate.Year == month.Year && item.CollectedDate.Month == month.Month)
            .DefaultIfEmpty()
            .Average(item => item?.Value ?? 0) // 无数据时设为0,若要null则改为item?.Value
    })
    .ToList();

3. 注意事项

  • 原代码中计算年份数时,startDate - endDate会得到负的时间跨度,需修正为endDate - startDate才能得到正确的天数差。
  • 如果数据中存在异常值(比如示例中2011年4月的481000),可以根据需求在分组前添加过滤逻辑,例如Where(item => item.Value < 100000)排除异常大的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:40:22