c# - 时间序列和关联策略

标签 c# algorithm time-series

我有各种时间序列,我想将它们关联起来并呈现为 csv 文件或内存数据表 (.NET)。这些时间序列是时间值对的数组(实际上,这些对象不仅包含时间和值)。时间序列可能跨越不同的重叠时期,有些甚至可能有漏洞(给定时间戳的缺失值)。

对于那些感兴趣的人,我正在使用 OPC HDA .NET 库从 OPC HDA 服务器中提取历史时间序列。

生成的数据表中的每个时间序列应有一列,所有时间序列均基于时间戳列按时间顺序排列。请参见下面的示例:

|-------|-------|-------|-------|-------|
   TIME    TS1     TS2     TS3     TS4
|-------|-------|-------|-------|-------|
    1       X               X       X
|-------|-------|-------|-------|-------|
    2       X       X       X       X
|-------|-------|-------|-------|-------|
    3       X       X               X
|-------|-------|-------|-------|-------|
    4       X       X       X 
|-------|-------|-------|-------|-------|
    5       X       X       X 
|-------|-------|-------|-------|-------|

实现这一目标的最有效方法是什么? “有效”是指使用最少的代码。但考虑到时间序列可能变得非常大,内存使用也可能是一个问题。

最佳答案

您可以首先扫描所有存在的系列以查找不同的值(例如,将它们聚合到 HashSet 中),然后简单地将它们转储到日期数组中(将日期和索引位置之间的匹配存储在字典中)。

var distinctDates = allSeries
  .SelectMany(s => s.Values.Select(v => v.Date))
  .Distinct()
  .OrderBy(d => d)
  .ToArray();

var datePositions = distinctDates
  .Select((d,index) => new 
    {
      Date = d,
      Index = index
    }).
  .ToDictionary(x => x.Date, x => x.Index);

然后,创建一个宽度为“NumberOfSeries”、长度为“NumberOfDates”的交错数组。之后,对所有数据进行第二次扫描并将它们转储到它们的位置。

var values = new float[allSeries.Length][];
for (var i=0;i<allSeries.Length;i++)
{
  values[i] = new float[distinctDates.Length];
  var currentSerie = allSeries[i];
  foreach(var value in currentSerie.Values)
  {
    var index = datePositions[value.Date];
    values[i][index] = value.Value;
  }      
}

我在没有接触 VisualStudio 的情况下编写了这段代码,所以我可能有一些错别字。或者可能会使用一些 .NET 中不存在的 LINQ 方法(只需查看 Lokad.Shared.dll )。但是您应该能够理解这一点。

更多的笔记,当我在讨论这个话题时:

  1. 如果您必须立即将所有内容保存在内存中,请使用锯齿状数组。它比字典更有效,而且内存问题比矩形数组少得多。

  2. 让 Value 对象尽可能小(即:float 而不是 double)。

  3. 如果预计 future 时间序列值的数量会变大,则永远不要将值以“每个值一行”的方式存储在数据库中。建议要么选择HDF之类的东西。 (具有 .NET 接口(interface))或在数据库中以二进制形式使用持久时间序列片段(如 time serie databases )

坚持这些应该可以让您扩展到数亿个时间值而不会出现很多问题(做到了)。

关于c# - 时间序列和关联策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1019907/

相关文章:

c# - 登录后如何在下一个表单的标签中显示欢迎用户名?

php - 从可变权重随机生成组合

r - XTS 尺寸限制

python - 聚合时间序列数据

c# - WPF:将ListBox的高度限制为网格行的高度

c# - radiobuttonlist 奇怪的 View

c# - 将实际值从 fortran77 dll 返回到 c#

java - 使用 '|' 或 '||' 运算符的递归在基本情况下不返回 false

python - 在 Pandas Python 中根据唯一列键对数据进行分组并连接(数据透视表)