使用基于时间戳的ReactiveX实现移动平均值

时间:2017-03-27 10:32:14

标签: c# system.reactive reactivex

我正在使用Rx.Net并且我有Observable发出时间序列点(double,timestamp)。每当新点到达时,我想从最后30秒计算平均值。我想我需要某种重叠的窗口/缓冲区,不是基于计数而是基于时间戳。

我在SlidingWindow实现中找到了this主题,但我无法弄清楚如何将其与我的问题相符。

编辑:

感谢this我了解到我可以使用扫描操作符并缓冲我的点,所以基本上这可以解决问题。但也许有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

BufferWindow期待,你想要回顾一些东西。 Scan是最好的起点:

public static IObservable<List<T>> BackBuffer<T>(this IObservable<T> source, TimeSpan ts)
{
    return BackBuffer(source, ts, Scheduler.Default);
}
public static IObservable<List<T>> BackBuffer<T>(this IObservable<T> source, TimeSpan ts, IScheduler scheduler)
{
    return source
        .Timestamp()
        .Scan(new List<Timestamped<T>>(), (list, element) => list
            .Where(ti => scheduler.Now - ti.Timestamp <= ts)
            .Concat(Enumerable.Repeat(element, 1))
            .ToList()
        )
        .Select(list => list.Select(t => t.Value).ToList());
}

一旦你有BackBuffer或类似的东西,其余的就变得容易了:

source
    .BackBuffer(TimeSpan.FromMilliseconds(70))
    .Select(list => list.Average())
    .Subscribe(average => Console.WriteLine(average));