2012-04-19 6 views
0

HardwarePerformanceという名前のクラスには、time、cpuUsagePercent、memoryUsagePercent、diskUsage、diskRead、diskWrite、latencyの各フィールドがあります。 統計データではないデータを格納するためにListオブジェクトを埋めました。 Linqコマンドでこれらすべてのフィールドの平均値を計算する必要があります。 私は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); 

このコードの構文は正しいです。しかし、同時にすべての平均値を計算したいのですが、コードを書くにはどうすればいいですか?

+1

我々は次回水平に自分をスクロールする必要がないように、あなたのコードをフォーマットしてください。 –

+0

ところで、なぜあなたのローカル変数は '_'で始まっていますか?これは本当に珍しい命名規則です。 – svick

+2

'_stats._time'を書いていないので、' _time'は '_stats'にどのように関連していますか? –

答えて

-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

+0

編集したコードは私には意味がありませんか? 「価値」とは何ですか?また、異なる値によるグループ分けは意味をなさないので、確かに平均を計算しません。 – svick

+0

あなたの答えをありがとう、私はこの解決策を試してみます。 –

1

LINQで、このための組み込みの方法はありません。コレクションを何度も繰り返していて、匿名のオブジェクトが大丈夫だと仮定しても構わない場合は、次のようなことができます(filteredStatsには平均したいデータが含まれています)。

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

これがあなたが望むものでない場合は、平均を自分で計算する必要があります。

+0

私は今このスタイルのようにプログラミングしています。あなたの答えに感謝します。 –

0

以下は、コードの大半ですが、1回の反復ですべての平均を計算します。

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

多くのコードは、とにかく、あなたの答えに感謝します。 –

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

これは 'time'の統計を単にフィルタリングするのとどのように違うのですか?フィルタリングされたリストのすべての平均を持つ陽気なオブジェクトを作りますか?グループ化は何を達成しますか? – Rawling

+0

@Rawling:グループ化により、1つのクエリですべての平均を持つ匿名型を選択できます。 –

+0

@ Rawling:あなたはこの質問の中核的な問題を理解していないのではないかと心配しています。時間通りにフィルターをかけてから、** all ** _averages_ only ** 1 **を選択することはできません。したがって、疑似グループを追加しました。 –

関連する問題