Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Linq统计具有平均值的数据_C#_Linq_Average - Fatal编程技术网

C# 使用Linq统计具有平均值的数据

C# 使用Linq统计具有平均值的数据,c#,linq,average,C#,Linq,Average,我有一个名为HardwarePerformance的类,它包含以下字段:时间、cpuUsagePercent、MemoryUsage Percent、diskUsage、diskRead、diskWrite和latency。 我必须填充一个列表对象来包含not统计数据。 我需要在Linq命令中计算所有这些字段的平均值。 我不知道如何用Linq得到平均值。下面是我写的代码,当然不正确 var _hardwarePerf = (from _stats in _statsList

我有一个名为HardwarePerformance的类,它包含以下字段:时间、cpuUsagePercent、MemoryUsage Percent、diskUsage、diskRead、diskWrite和latency。 我必须填充一个列表对象来包含not统计数据。 我需要在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);

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

您可以使用Group,然后使用平均投影进行计算

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中没有用于此的内置方法。如果您不介意对集合进行多次迭代,并且假设匿名对象适合您,则可以执行以下操作,其中filteredStats包含要平均的数据,可能是按时间过滤的数据:

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

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

以下内容将在一次迭代中计算所有平均值,尽管这需要大量代码

注意,我假设时间是stats对象上的一个属性,否则选择时间的位置就没有多大意义

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();

请格式化您的代码,以便下次您不需要水平滚动。顺便说一句,为什么您的局部变量以x开头?这是一个非常不寻常的命名约定。既然您没有编写_stats._time,那么_time与_stats有什么关系?您如何使用它一次计算所有字段的平均值?编辑的代码对我来说没有任何意义?什么是价值?你按不同的值分组没有任何意义,它当然也不会计算平均值。谢谢你的回答,我会尝试这个解决方案。这与只是按时筛选统计数据,然后使用筛选列表中的所有平均值创建一个不同步的对象有何不同?分组有什么作用?@Rawling:分组可以在一次查询中选择所有平均值的匿名类型。@Rawling:恐怕你还没有理解这个问题的核心问题。您不能按时筛选然后仅选择1的所有平均值。因此我添加了伪组。我知道标准Linq平均值只能得到一个平均值。我没有看到执行虚拟分组和纯选择的实用程序,因此您可以在单个WTF Linq语句中获得所有平均值。我同意你的第二个解决方案是获得所有平均值的最简单、最容易阅读的方法,并且确实应该是公认的答案,因为OP显然不关心对结果进行多次迭代。我现在喜欢这种编程方式,谢谢你的回答。
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);
// ....