【问题标题】:c# LINQ questionc# LINQ 问题
【发布时间】:2011-07-07 23:21:38
【问题描述】:

我有一个包含多个组的数据集。

我必须计算两件事:

每组一些数据的平均值——我用下面的代码完成了:

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 做到这一点?

谢谢。

编辑:感谢我的问题有点含糊;我知道如何计算标准偏差,我想知道如何提取每个组的值列表(如上)以允许执行计算。谢谢。

【问题讨论】:

标签: c# linq


【解决方案1】:

达伦,

只是一个快速的 SO linq(双关语!)让你继续,直到得到进一步的答案:

Standard deviation of generic list?

希望对你有帮助

[edit] - 根据上面的 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))
                      };

尚未测试,因此可能无法立即工作,但理论是存在的。

【讨论】:

  • 谢谢,但我知道如何计算标准差,我真的需要知道如何根据上面的分组键从数据表中提取值列表
  • Darren - 如果您周围有足够的烟雾和镜子,上述编辑可能会起作用:)
  • 对匿名类型稍作调整即可完美工作。谢谢。
  • 这是变化(如果您有兴趣) stdDev = grp.Select(c => (Convert.ToDouble(c.Field(average)))).ToList().StandardDeviation (),
  • 很高兴为您工作 - 不错...还请注意,自第一次尝试以来,我已经稍微更改了扩展方法 sig,因此希望您可以在没有 ToList() 的情况下调用,如果您更改您要匹配的代码。
【解决方案2】:

这是关于计算标准偏差的 SO 问题/答案: Standard Deviation in LINQ

对于项目列表,只需执行 items = grp.ToList()grp.Select(c =&gt; 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))))
                  };

【讨论】:

  • 谢谢,但我知道如何计算标准差,我真的需要知道如何根据上面的分组键从数据表中提取值列表。
  • @Darren - grp 包含每个分组键的行。从相关列中获取您对平均计算所做的值,并使用它来进行计算。例如grp.Select(c =&gt; c.Field....))
猜你喜欢
  • 1970-01-01
  • 2010-12-19
  • 2011-03-02
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多