1

我正在使用动态移动窗口来计算按日期键排序的系列的简单统计数据。我希望能够在窗口末尾设置边界。例如具有每月移动平均线的时间序列,每月由

(fun d1 d2 -> d1.addMonths(1) <= d2)

然而deedle系列功能

windowWhileInto cond f series

总是使用开始作为边界。因此,它总是从第一个数据实例为接下来的 n 个数据点创建一个数据点系列(n 由上面的乐趣决定)。我想从第 n 个数据中获得一个数据点系列,然后回顾过去。

我也尝试使用Series.Revfirst 来反转系列,但 deedle 认为该系列虽然以相反的顺序不再排序。

我正在寻找的可能吗?

4

1 回答 1

3

如果您查看文档中的聚合函数列表,您会发现一个函数aggregate是所有窗口和分块函数的泛化,并且还带有一个键选择器。

这意味着您可以执行以下操作:

ts |> Series.aggregateInto
        (WindowWhile(fun d1 d2 -> d1.AddMonths(1) >= d2))  // Aggregation to perform
        (fun seg -> seg.Data.LastKey())                    // Key selector (use last)
        (fun ds -> OptionalValue(ds.Data))                 // Value selector

该函数采用 3 个参数,包括键选择器和一个获取“数据段”的函数(它具有窗口和一个标志,无论它是完整的还是不完整的 - 例如在窗口结束时)。

遗憾的是,这在这里不太适用,因为它会创建一个带有重复键的系列(Deedle 不支持这些键)。块末尾的窗口都将以相同的日期结束,因此您将获得重复的键(它实际上运行,但您不能对系列做太多事情)。

一个丑陋的解决方法是记住最后一个块的结尾,并在结尾开始重复时返回缺失值:

let lastKey = ref None
let r = 
  ts |> Series.aggregateInto
      (WindowWhile(fun d1 d2 -> d1.AddMonths(1) >= d2)) (fun seg -> seg.Data.LastKey())
      (fun ds -> 
         match lastKey.Value, ds.Data.LastKey() with 
         | Some lk, clk when lk = clk -> OptionalValue.Missing
         | _, clk -> lastKey := Some clk; OptionalValue(ds.Data))
     |> Series.dropMissing

编辑:我为此记录了一个 GitHub 问题

于 2014-08-06T10:52:42.870 回答