在 Deedle 系列中找到满足条件的第一个 window
Find the first window satisfying a condition in a Deedle Series
给定一个以时间作为行索引的 Deedle 系列,我需要找到信号首次满足条件的时间(在本例中,保持低于 0.005 50 毫秒)。
目前我移动了 50 毫秒 window 并根据每个 window 的开始时间和最大值创建了一个序列,然后得到第一个最大值 < 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;
问题是即使第一个 window 满足条件,它也会搜索整个系列(可能会变得非常大)。
有没有一种简单的方法可以在找到第一个 window 时停止,而不是搜索整个系列?
好吧,我找不到 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
的优雅方法,但速度明显较慢。因此,除非有人有 simpler/better 解决方案,否则这样做就可以了。
给定一个以时间作为行索引的 Deedle 系列,我需要找到信号首次满足条件的时间(在本例中,保持低于 0.005 50 毫秒)。
目前我移动了 50 毫秒 window 并根据每个 window 的开始时间和最大值创建了一个序列,然后得到第一个最大值 < 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;
问题是即使第一个 window 满足条件,它也会搜索整个系列(可能会变得非常大)。
有没有一种简单的方法可以在找到第一个 window 时停止,而不是搜索整个系列?
好吧,我找不到 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
的优雅方法,但速度明显较慢。因此,除非有人有 simpler/better 解决方案,否则这样做就可以了。