2015-08-20 82 views
0

給定一個將時間作爲行索引的Deedle系列,我需要找到信號第一次滿足條件的時間(在這種情況下,保持低於0.005,50ms) 。查找滿足條件的第一個窗口

目前我拿一個50ms的移動窗口,並從每個窗口的開始時間和最大值創建一個序列,然後得到第一個,其最大值爲< 0.005。它工作得很好,但可能效率很低。

// Assume a timestep of 1ms 
int numSteps = 50; 

// Create a series from the first index and max of each window 
var windowMaxes = mySeries.WindowInto(
    numSteps, 
    s => new KeyValuePair<double, double>(s.FirstKey(), s.Max())); 
var zeroes = windowMaxes.Where(kvp => kvp.Value <= 0.005); 

// Set to -1 if the condition was never satisfied 
var timeOfZero = zeroes.KeyCount > 0 ? zeroes.FirstKey() : -1D; 

的問題是,它搜索整個系列(這可能會變得非常大),即使第一窗口滿足條件。

有沒有簡單的方法來做到這一點,但停止當第一個窗口被發現,而不是搜索整個系列?

回答

1

嗯,我無法找到一個Deedly一行程序或任何方便的LINQ命令來做到這一點,所以我寫了下面的擴展方法:

public static K FirstWindowWhere<K, V>(
    this Series<K, V> series, 
    Func<V, bool> condition, 
    int windowSize) 
{ 
    int consecutiveTrues = 0; 
    foreach (var datum in series.Observations) 
    { 
     if (condition(datum.Value)) 
     { 
      consecutiveTrues++; 
     } 
     else 
     { 
      consecutiveTrues = 0; 
     } 

     if (consecutiveTrues == windowSize) 
     { 
      return datum.Key; 
     } 
    } 
    return default(K); 
} 

要與我的上述條件撥打:

double zeroTime = mySeries.FirstWindowWhere(d => d <= 0.005, numSteps); 

我嘗試了幾種不同的方法,包括使用Series.Between而不是Series.GetObservations的漂亮優雅的方法,但速度明顯較慢。因此,除非有人有更簡單/更好的解決方案,否則這樣做。