2011-03-03 60 views
1

我有一個具有多個組的數據集。c#LINQ問題

我算算兩件事情:

每組一些數據的平均值 - 這是我用下面的代碼完成:

var results = from res in dt.AsEnumerable() 
         group res by res.Field<string>(key) 
          into grp 
          orderby Convert.ToInt32(grp.Key) 
          select new 
          { 
           date = grp.Key, 
           sum = grp.Average(r => Convert.ToDouble(r.Field<string> (average))) 

          }; 

我還需要計算的標準偏差每個組的值,因此對於每個組,我需要創建一個數組或每個組的單個結果列表。我怎麼能用LINQ來做到這一點?

謝謝。

編輯:我很欣賞我的問題,我有點模糊;我知道如何計算標準偏差,我想知道如何提取每個組的值列表(如上所述)以允許執行計算。謝謝。

+2

部分,http://stackoverflow.com/questions/2253874/linq-equivalent-for-standard-deviation – 2011-03-03 10:53:53

回答

1

達倫,

只是一個快速的SO LINQ(雙關打算!!)讓你去直到進一步的答案到達:

Standard deviation of generic list?

希望這有助於

[編輯] - 基於上面的SO鏈接,你可以修改這一點,嘗試(靜態類中):

public static double StdDev(this IEnumerable<double> values) 
{ 
    double ret = 0; 
    if (values.Count() > 0) 
    {  
    //Compute the Average  
    double avg = values.Average(); 
    //Perform the Sum of (value-avg)_2_2  
    double sum = values.Sum(d => Math.Pow(d - avg, 2)); 
    //Put it all together  
    ret = Math.Sqrt((sum)/(values.Count()-1)); 
    } 
    return ret; 
} 

再加上一點點覆蓋(我已經處理了,但後來改變了看這個鏈接http://help.syncfusion.com/ug_84/User%20Interface/WPF/Grid/default.htm?turl=Documents%2Fcustomsummaries.htm):

public static double StdDev<T>(this IEnumerable<T> values, Func<T, double?> selector) 
{ 
    double ret = 0; 
    var count = values.Count(); 

    if (count > 0) 
    { 
     // Compute the Average 
     double? avg = values.Average(selector); 

     // Perform the Sum of (value-avg)^2 
     double sum = values.Select(selector).Sum(d => 
     { 
      if (d.HasValue) 
      { 
       return Math.Pow(d.Value - avg.Value, 2); 
      } 
      return 0.0; 
     }); 

     // Put it all together 
     ret = Math.Sqrt((sum)/(count - 1)); 
    } 
    return ret; 
} 

,然後簡單地套用這樣:

var results = from res in dt.AsEnumerable() 
        group res by res.Field<string>(key) 
         into grp 
         orderby Convert.ToInt32(grp.Key) 
         select new 
         { 
          date = grp.Key, 
          sum = grp.Average(r => Convert.ToDouble(r.Field<string>(average))), 
          stdDev = gp.Select(s => Convert.ToDouble(s.Field<string>(average))).StdDev(), 
          // alternative override - note no need to convert 
          stdDev2 = gp.StdDev(s => s.Field<string>(average)) 
         }; 

沒有測試過,所以可能無法馬上,但理論上是存在的。

+0

謝謝,但我知道如何計算標準偏差,我真的需要知道如何從數據表中提取基於我的值將上面的關鍵分組 – 2011-03-03 10:59:56

+0

達倫 - 如果你有足夠的煙霧和鏡子鋪設在周圍,上面的編輯可能會有效:) – 2011-03-03 11:24:34

+0

對匿名類型進行一些調整後,工作完美無缺。謝謝。 – 2011-03-03 11:34:41

1

這裏有一個計算標準偏差SO提問/回答: Standard Deviation in LINQ

對於項目的列表只是做items = grp.ToList()grp.Select(c => c.Field...).ToList()

var results = from res in dt.AsEnumerable() 
       group res by res.Field<string>(key) 
       into grp 
       orderby Convert.ToInt32(grp.Key) 
       select new 
        { 
        date = grp.Key, 
        sum = grp.Average(r => Convert.ToDouble(r.Field<string>(average))), 
        items = grp.ToList(), 
        sd = CalcSD(grp.Select(c => Convert.ToDouble(r.Field<string>(average)))) 
        }; 
+0

謝謝,但我知道如何計算標準偏差,我真的需要知道如何提取列表來自數據表的值基於我上面的分組鍵。 – 2011-03-03 10:58:04

+1

@達倫 - 'grp'包含每個分組鍵的行。按照相關列中的平均值計算獲取值,然後使用該值進行計算。例如'grp.Select(c => c.Field ....)') – 2011-03-03 11:01:24