我有一个时间戳列表(以滴答为单位),我想从这个列表中创建另一个表示条目之间的增量时间的列表。
例如,我的主时间表如下所示:
- 10
- 20
- 30
- 50
- 60
- 70
我要返回的是这个:
- 10
- 10
- 20
- 10
- 10
我在这里试图完成的是通过计算标准偏差来检测输出表中的 #3 是否为离群值。我以前没有进行过统计,但我认为如果我在输出列表中查找普遍值并丢弃 1 sigma 之外的任何值,这对我来说就足够了。
我希望能够使用单个 LINQ 查询创建输出列表,但我还没有弄清楚。目前我只是用循环暴力破解它。
最佳答案
如果您运行的是 .NET 4.0,这应该可以正常工作:
var deltas = list.Zip(list.Skip(1), (current, next) => next - current);
除了多个枚举器之外,这是非常有效的;它应该适用于任何类型的序列。
这是 .NET 3.5 的替代方案:
var deltas = list.Skip(1)
.Select((next, index) => next - list[index]);
显然,这个想法只有在使用列表的索引器时才会有效。修改它以使用 ElementAt
可能不是一个好主意:非 IList<T>
将出现二次运行时间序列。在这种情况下,编写自定义迭代器是一个很好的解决方案。
编辑:如果您不喜欢 Zip
+ Skip(1)
想法,编写这样的扩展(未经测试)可能在这些情况下有用:
public class CurrentNext<T>
{
public T Current { get; private set; }
public T Next { get; private set; }
public CurrentNext(T current, T next)
{
Current = current;
Next = next;
}
}
...
public static IEnumerable<CurrentNext<T>> ToCurrentNextEnumerable<T>(this IEnumerable<T> source)
{
if (source == null)
throw new ArgumentException("source");
using (var source = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
yield break;
T current = enumerator.Current;
while (enumerator.MoveNext())
{
yield return new CurrentNext<T>(current, enumerator.Current);
current = enumerator.Current;
}
}
}
然后您可以将其用作:
var deltas = list.ToCurrentNextEnumerable()
.Select(c=> c.Next - c.Current);
关于c# - 使用 LINQ 创建增量值的 IEnumerable<>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3874013/