繁体   English   中英

使用Linq统计平均值

[英]Use Linq to statistics data with average

我有一个名为HardwarePerformance的类,其中包含以下字段:time,cpuUsagePercent,memoryUsagePercent,diskUsage,diskRead,diskWrite,latency。 我已经填充了一个List对象以包含非统计数据。 我需要在Linq命令中计算所有这些字段的平均值。 我不知道如何使用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);

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

LINQ中没有内置方法。 如果您不介意要对集合进行多次迭代,并假设可以使用匿名对象,则可以执行以下操作(其中filteredStats包含要平均的数据,可能按时间过滤了):

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

如果这不是您想要的,则可能必须自己计算平均值。

尽管有很多代码,但下面的代码可以一次迭代地计算所有平均值。

请注意,我假设time是您的stats对象的属性,否则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
};

您可以在单独的语句中执行此操作,也可以通过这种不太直观的方式进行操作:

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);
// ....

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

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平均

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM