c# - LINQ 按时间段聚合和分组

标签 c# linq aggregate-functions

我正在尝试了解如何使用 LINQ 按时间间隔对数据进行分组;然后理想地聚合每个组。

找到大量具有明确日期范围的示例,我尝试按 5 分钟、1 小时、1 天等时间段进行分组。

例如,我有一个用值包装 DateTime 的类:

public class Sample
{
     public DateTime timestamp;
     public double value;
}

这些观察结果作为一系列包含在列表集合中:

List<Sample> series;

因此,为了按小时分组并按平均值汇总值,我正在尝试执行以下操作:

var grouped = from s in series
              group s by new TimeSpan(1, 0, 0) into g
              select new { timestamp = g.Key, value = g.Average(s => s.value };

这是一个根本性的缺陷,因为它对 TimeSpan 本身进行了分组。我不明白如何在查询中使用 TimeSpan(或表示间隔的任何数据类型)。

最佳答案

您可以将时间戳四舍五入到下一个边界(即向下到过去最近的 5 分钟边界)并将其用作您的分组:

var groups = series.GroupBy(x =>
{
    var stamp = x.timestamp;
    stamp = stamp.AddMinutes(-(stamp.Minute % 5));
    stamp = stamp.AddMilliseconds(-stamp.Millisecond - 1000 * stamp.Second);
    return stamp;
})
.Select(g => new { TimeStamp = g.Key, Value = g.Average(s => s.value) })
.ToList();

上面通过在分组中使用修改后的时间戳来实现这一点,它将分钟设置为前 5 分钟的边界并删除秒和毫秒。同样的方法当然可以用于其他时间段,即小时和天。

编辑:

基于此组成示例输入:

var series = new List<Sample>();
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(3) });
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(4) });
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(5) });
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(6) });
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(7) });
series.Add(new Sample() { timestamp = DateTime.Now.AddMinutes(15) });

为我生成了 3 组,一组的分组时间戳为 3:05,一组为 3:10,一组为下午 3:20(您的结果可能因当前时间而异)。

关于c# - LINQ 按时间段聚合和分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8856266/

相关文章:

c# - .NET Core Entity Framework 存储过程

c# - 将大量对象有效地匹配到 csv 标题映射

c# - 为什么我们不能锁定一个值类型?

c# - 如何使用 LINQ 从 List<string> 中删除重复组合

c# - XDocument.Save() 时出现内存异常

c# - 如何在不对列进行硬编码的情况下在 LINQ 中转换数据

c# - 从球员位置列表中找到最大可能的总分

mysql - 如何从一个表中获取与其他表中的聚合函数相关的信息

mysql - 如何在没有聚合和分组的情况下在 MySQL 中查找最多两个项目

javascript - 更改 amCharts 数据的粒度