我有一个名为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);
此代码的语法是正确的。但是我想同时计算所有的平均值,我该如何编写代码?
答案 0 :(得分:1)
LINQ中没有内置方法。如果你不介意你将多次迭代该集合,并假设一个匿名对象可以为你做,你可以做这样的事情(其中filteredStats
包含你想要平均的数据,可能是过滤的时间):
var averages =
new
{
Latency = filteredStats.Average(x => x.Latency),
CpuUsagePercent = filteredStats.Average(x => x.CpuUsagePercent),
…
};
如果这不是您想要的,您可能需要自己计算平均值。
答案 1 :(得分: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
};
答案 2 :(得分: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);
// ....
答案 3 :(得分:-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
};