使用Linq进行平均,同时干净地忽略0

时间:2014-01-09 15:28:02

标签: c# linq datatable average

我有一个linq语句,它平均DataTable中的行并将它们显示在图表上,按日期和时间分组。

有一个大问题:由于一天中的特定时间根本没有发生任何事情,因此返回了许多0值。这些都使我的平均值有些糟糕

一天中不同的时间可能在不同的列中有0,所以我不能只删除列中的每一行(干净利落),因为我最终没有在数据表中留下任何行,或者至少我在任何情况下都无法想到干净利落的方式。

这就是我所拥有的:

            var results = from row2 in fiveDayDataTable.AsEnumerable()
                          group row2 by ((DateTime)row2["TheDate"]).TimeOfDay
                              into g
                              select new
                              {
                                  Time = g.Key,
                                  AvgItem1 = g.Average(x => (int)x["Item1"]),
                                  AvgItem2 = g.Average(x => (int)x["Item2"]),
                                  AvgItem3 = g.Average(x => (int)x["Item3"]),
                                  AvgItem4 = g.Average(x => (int)x["Item4"]),
                                  AvgItem5 = g.Average(x => (int)x["Item5"]),
                              };

我不知道这是否可行,所以我想我会问 - 有没有办法在没有0的情况下做平均值?

谢谢!

3 个答案:

答案 0 :(得分:4)

当然你可以过滤掉零:

AvgItem1 = g.Select(x => (int)x["Item1"]).Where(x => x != 0).Average(),
AvgItem2 = g.Select(x => (int)x["Item2"]).Where(x => x != 0).Average(),
AvgItem3 = g.Select(x => (int)x["Item3"]).Where(x => x != 0).Average(),
AvgItem4 = g.Select(x => (int)x["Item4"]).Where(x => x != 0).Average(),
AvgItem5 = g.Select(x => (int)x["Item5"]).Where(x => x != 0).Average(),

如果您的结果集(Where之后)可能为空,则可能需要致电DefaultIfEmpty

AvgItem1 = g.Select(x => (int)x["Item1"]).Where(x => x != 0).DefaultIfEmpty(0).Average(),

这将返回非空结果集,以便Average能够使用它。

答案 1 :(得分:1)

由于你有很多重复,你可以考虑将你的平均逻辑重构为一个单独的方法或匿名函数:

Func<IEnumerable<YourClass>, string, double> avg = 
    (g, name) => g.Select(x => (int)x[name]).Where(x => x != 0).Average();

var results = from row2 in fiveDayDataTable.AsEnumerable()
              group row2 by ((DateTime)row2["TheDate"]).TimeOfDay
              into g
              select new
              {
                  Time = g.Key,
                  AvgItem1 = avg(g, "Item1"),
                  AvgItem2 = avg(g, "Item2"),
                  AvgItem3 = avg(g, "Item3"),
                  AvgItem4 = avg(g, "Item4"),
                  AvgItem5 = avg(g, "Item5"),
              };

答案 2 :(得分:0)

Where之前的每个查询中添加Average,确保该项目不等于零。