Dav*_*ave 12 c# linq statistics .net-3.5
我有一个时间戳列表(以刻度表示),从这个列表中我想创建另一个表示条目之间的增量时间的列表.
我们只是说,例如,我的主时间表如下所示:
我想要的是这个:
我在这里要完成的是通过计算标准偏差来检测输出表中的#3是异常值.我以前没有统计过,但我想如果我在输出列表中查找流行值并丢弃1 sigma之外的任何内容,这对我来说就足够了.
我希望能够使用单个LINQ查询创建输出列表,但我还没有想出来.目前我只是通过循环强制它.
Ani*_*Ani 16
如果您运行的是.NET 4.0,这应该可以正常工作:
var deltas = list.Zip(list.Skip(1), (current, next) => next - current);
Run Code Online (Sandbox Code Playgroud)
除了多个调查员,这是非常有效的; 它应该适用于任何类型的序列.
这是.NET 3.5的替代方案:
var deltas = list.Skip(1)
.Select((next, index) => next - list[index]);
Run Code Online (Sandbox Code Playgroud)
显然,这个想法只有在使用列表的索引器时才会有效.修改它以使用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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将其用作:
var deltas = list.ToCurrentNextEnumerable()
.Select(c=> c.Next - c.Current);
Run Code Online (Sandbox Code Playgroud)