2012-04-19 75 views
0

我有一个名为HardwarePerformance的类包含这些字段:time,cpuUsagePercent,memoryUsagePercent,diskUsage,diskRead,diskWrite,latency。 我已经填充List对象来包含非统计数据。 我需要计算Linq命令中所有这些字段的平均值。 我不知道如何获得Linq的平均值。 Follow是我写的代码(当然是不正确的)。使用Linq来统计数据的平均值

var _hardwarePerf = (from _stats in _statsList 
        where _time>=DateTime.Parse("2012-04-04 00:00:00") 
         &&_time<=DateTime.Parse("2012-04-04 11:00:00") 
        select new { 
          Latency = _stats.latency, 
          CpuUsagePercent = _stats.cpuUsagePercent, 
          MemoryUsagePercent = _stats.memoryUsagePercent, 
          DiskUsage = _stats.diskUsage, DiskRead = _stats.diskRead, 
          DiskWrite = _stats.diskWrite 
        }).Average(Latency => Latency.Latency); 

该代码的语法是正确的。但我想同时计算所有的平均值,我该如何编写我的代码?

+1

请格式化你的代码,这样我们就不需要水平下一次自己滚动。 – 2012-04-19 07:14:35

+0

顺便说一句,为什么你的局部变量以'_'开头?这是一个非常不寻常的命名约定。 – svick 2012-04-19 07:20:41

+2

'_time'与'_stats'相关,因为你没有写'_stats._time'? – 2012-04-19 07:22:24

回答

-2

您可以使用“分组依据”,然后您可以使用平均投影来计算。

var query = from _stats in _statsList 
    group _stats by new { 
       Latency = _stats.latency, 
       CpuUsagePercent = _stats.cpuUsagePercent, 
       MemoryUsagePercent = _stats.memoryUsagePercent, 
       DiskUsage = _stats.diskUsage, 
       DiskRead = _stats.diskRead, 
       DiskWrite = _stats.diskWrite 

    } into myGroup 
    select new { 
     AverageVal = myGroup.Average(x => x.Value), 
     CpuUsagePercent = myGroup.Key.CpuUsagePercent, 
     ... // the rest of your projection 
}; 

LINQ Average

+1

你将如何使用它来一次计算所有字段的平均值? – svick 2012-04-19 07:26:41

+0

编辑的代码对我没有任何意义?什么是“价值”?而你用不同的值进行分组没有任何意义,它当然不会计算平均值。 – svick 2012-04-19 08:14:40

+0

感谢您的回答,我会尝试此解决方案。 – 2012-04-19 08:40:22

1

有一个在LINQ对此没有内置的方法。如果您不介意多次迭代集合,并假设匿名对象对您可以,则可以这样做(其中filteredStats包含要平均的数据,可能按时间过滤):

var averages = 
    new 
    { 
     Latency = filteredStats.Average(x => x.Latency), 
     CpuUsagePercent = filteredStats.Average(x => x.CpuUsagePercent), 
     … 
    }; 

如果这不是你想要的,你可能需要自己计算平均值。

+0

我现在编程就像这种风格,谢谢你的回答。 – 2012-04-19 08:39:19

0

以下计算一次迭代中的所有平均值,虽然它有很多代码。

请注意,我假设time是您的统计资料对象的属性,否则您的select where time没有多大意义。

var _hardwareAccumulator = 
    _statsList 
     .Where(s => 
      s.time >= DateTime.Parse("2012-04-04 00:00:00") && 
      s.time <= DateTime.Parse("2012-04-04 11:00:00")) 
     .Aggregate(
      new 
      { 
       count = 0, 
       cpuUsagePercent = 0.0, 
       memoryUsagePercent = 0.0, 
       diskUsage = 0.0, 
       diskRead = 0.0 
      }, 
      (acc, s) => 
       new 
       { 
        count = acc.count + 1, 
        cpuUsagePercent = 
         acc.cpuUsagePercent + s.cpuUsagePercent, 
        memoryUsagePercent = 
         acc.memoryUsagePercent + s.memoryUsagePercent, 
        diskUsage = 
         acc.diskUsage + s.diskUsage, 
        diskRead = 
         acc.diskRead + s.diskRead 
       } 
      ); 
var _hardwarePerf = new 
{ 
    cpuUsagePercent = 
     _hardwareAccumulator.cpuUsagePercent/_hardwareAccumulator.count, 
    memoryUsagePercent = 
     _hardwareAccumulator.memoryUsagePercent/_hardwareAccumulator.count, 
    diskUsage = 
     _hardwareAccumulator.diskUsage/_hardwareAccumulator.count, 
    diskRead = 
     _hardwareAccumulator.diskRead/_hardwareAccumulator.count 
}; 
+0

很多代码,无论如何,谢谢你的回答。 – 2012-04-19 08:39:54

0

你要么东东做,在单独的语句或者你可以做到这一点在这不是很直观的方式:

var averages = statsList.Where(s => s.time >= new DateTime(2012, 4, 4) && s.time <= new DateTime(2012, 4, 04, 11, 0, 0)) 
      .GroupBy(s => 1) 
      .Select(grp => new 
      { 
       Latency = grp.Average(s => s.latency), 
       CpuUsagePercent = grp.Average(s => s.cpuUsagePercent), 
       MemoryUsagePercent = grp.Average(s => s.memoryUsagePercent), 
       DiskUsage = grp.Average(s => s.diskUsage), 
       DiskRead = grp.Average(s => s.diskRead), 
       DiskWrite = grp.Average(s => s.diskWrite) 
      }).FirstOrDefault(); 

注意.GroupBy(s => 1)只是为了能够计算平均每个属性。另请注意,我已从您的房产名称中删除下划线,并将时间添加到您的班级。

另一种方法更容易阅读:

var theStats = statsList.Where(s => s.time >= new DateTime(2012, 4, 4) && s.time <= new DateTime(2012, 4, 04, 11, 0, 0)); 
var Latency = theStats.Average(s => s.latency); 
var CpuUsagePercent = theStats.Average(s => s.cpuUsagePercent); 
// .... 
+1

这与从“时间”过滤统计数据,然后用过滤列表中的所有平均值生成一个有害对象的方式有什么不同?分组实现了什么? – Rawling 2012-04-19 07:51:19

+0

@Rawling:通过分组,可以在一个查询中选择具有所有平均值的匿名类型。 – 2012-04-19 09:21:52

+0

@Rawling:恐怕你还没有明白这个问题的核心问题。您无法按时过滤,然后选择**全部** _只限于_ ** 1 **。因此我添加了伪组。 – 2012-04-19 09:49:43