背景:我有一系列连续的,带时间戳的数据.数据序列中有孔,有些大,有些只有一个缺失值.
每当孔只是一个缺失值时,我想使用虚拟值修补孔(较大的孔将被忽略).
我想使用延迟生成修补序列,因此我使用Seq.unfold.
我已经制作了两个版本的方法来修补数据中的漏洞.
第一个消耗带有孔的数据序列并产生修补序列.这就是我想要的,但是当输入序列中的元素数量超过1000时,方法运行得非常慢,并且输入序列包含的元素越多,它就会越来越差.
第二种方法使用带有孔的数据列表并生成修补序列并且运行速度很快.然而,这不是我想要的,因为这会强制整个输入列表在内存中的实例化.
我想使用(sequence - > sequence)方法而不是(list - > sequence)方法,以避免在内存中同时存在整个输入列表.
问题:
1)为什么第一种方法如此缓慢(使用较大的输入列表逐渐变得更糟)(我怀疑它与使用Seq.skip 1重复创建新序列有关,但我不确定)
2)如何使用输入序列而不是输入列表快速修补数据中的空洞?
代码:
open System
// Method 1 (Slow)
let insertDummyValuesWhereASingleValueIsMissing1 (timeBetweenContiguousValues : TimeSpan) (values : seq<(DateTime * float)>) =
let sizeOfHolesToPatch = timeBetweenContiguousValues.Add timeBetweenContiguousValues // Only insert dummy-values when the gap is twice the normal
(None, values) |> Seq.unfold (fun (prevValue, restOfValues) ->
if restOfValues |> Seq.isEmpty then
None // Reached the …Run Code Online (Sandbox Code Playgroud) 背景:
我有一系列连续的,带时间戳的数据.数据序列中存在间隙,其中数据不连续.我想创建一种方法将序列分成序列序列,以便每个子序列包含连续数据(在间隙处分割输入序列).
约束:
方法签名
let groupContiguousDataPoints (timeBetweenContiguousDataPoints : TimeSpan) (dataPointsWithHoles : seq<DateTime * float>) : (seq<seq< DateTime * float >>)= ...
Run Code Online (Sandbox Code Playgroud)
从表面上看,问题看起来微不足道,但即使采用Seq.pairwise,IEnumerator <_>,序列理解和屈服声明,解决方案也让我望而却步.我确信这是因为我仍然缺乏组合F#-idioms的经验,或者可能是因为我还没有接触过一些语言结构.
// Test data
let numbers = {1.0..1000.0}
let baseTime = DateTime.Now
let contiguousTimeStamps = seq { for n in numbers ->baseTime.AddMinutes(n)}
let dataWithOccationalHoles = Seq.zip contiguousTimeStamps numbers |> Seq.filter (fun (dateTime, num) -> num % 77.0 <> 0.0) // Has a gap in the data every …Run Code Online (Sandbox Code Playgroud)