我有一系列项目,我想从中抽样.
我的印象是,Set会有一个好的结构来取样,在折叠中我会回复原始或修改后的元素,如果我想要替换不是,则将检索到的元素丢失.但是,似乎没有方法直接从Set检索元素.
有什么我想念的吗?或者我应该使用一组索引,以及一个随机开始的代理函数,position < Set.count直到它找到一个成员为止?
也就是说,沿着这条线
module Seq =
let modulo (n:int) start =
let rec next i = seq { yield (i + 1)%n ; yield! next (i+1)}
next start
module Array =
let Sample (withReplacement:bool) seed (entries:'T array) =
let prng, indexes = new Random(seed), Set(Seq.init (entries |> Array.length) id)
Seq.unfold (fun set -> let N = set |> Set.count
let next = Seq.modulo N (prng.Next(N)) |> Seq.truncate N |> Seq.tryFind(fun i -> set |> Set.exists ((=) i))
if next.IsSome then
Some(entries.[next.Value], if withReplacement then set else Set.remove next.Value set)
else
None)
Run Code Online (Sandbox Code Playgroud)
编辑:积极跟踪我给出的内容,而不是跟踪我仍然可以提供的内容将使其更简单,更有效.
对于无需替换的采样,您可以只置换源seq并采用您想要采样的许多元素
let sampleWithoutReplacement n s =
let a = Array.ofSeq s
seq { for i = a.Length downto 1 do
let j = rnd.Next i
yield a.[j]
a.[j] <- a.[i - 1] }
|> Seq.take n
Run Code Online (Sandbox Code Playgroud)
向样品与更换,只需选择从源SEQ随机元素的n倍
let sampleWithReplacement n s =
let a = Array.ofSeq s
Seq.init n (fun _ -> a.[rnd.Next(a.Length)])
Run Code Online (Sandbox Code Playgroud)
然而,这些可能不是具有大量数据集的最有效方法
| 归档时间: |
|
| 查看次数: |
366 次 |
| 最近记录: |