Go 戈朗未更换样品
在golang,不更换切片的最佳取样方式是什么Go 戈朗未更换样品,go,random,slice,sampling,Go,Random,Slice,Sampling,在golang,不更换切片的最佳取样方式是什么 a := make([]int, 100) for i := range a { a[i] = i } # TODO sample 5 elements from a without replacement. 如果集合大小总体上相对较小,或者您正在对集合的大部分进行采样,最简单的方法是对元素进行无序排列,然后选择第一个n: rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j],
a := make([]int, 100)
for i := range a {
a[i] = i
}
# TODO sample 5 elements from a without replacement.
如果集合大小总体上相对较小,或者您正在对集合的大部分进行采样,最简单的方法是对元素进行无序排列,然后选择第一个
n
:
rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
fmt.Println(a[:5])
如果您不想洗牌整个集合,但改变集合的顺序(或复制整个集合)是可以接受的,那么您可以通过从切片中删除使用的值来更有效地“记录”使用的值
// create a copy of the slice header
c := a
samples := make([]int, n)
for i := 0; i < n; i++ {
r := int(rand.Int63n(int64(len(c))))
samples[i] = c[r]
// remove the sample from the copy slice
c[r], c[len(c)-1] = c[len(c)-1], c[r]
c = c[:len(c)-1]
}
//创建切片头的副本
c:=a
样本:=制造([]整数,n)
对于i:=0;i
如果集合的大小相当大,并且只对一小部分进行采样,则可以通过记录样本索引而不重复它,从原始集合中进行采样,而无需修改。显然,随着样本大小与集合大小之比的增加,碰撞的数量将增加,从而降低效率
例如:
// record indexes here to prevent duplicates
indexes := make(map[int]bool)
// create n random indexes
for i := 0; i < n; i++ {
var r int
for {
r = int(rand.Int63n(int64(len(a))))
if indexes[r] {
continue
}
break
}
indexes[r] = true
}
samples := make([]int, 0, n)
for i := range indexes {
samples = append(samples, a[i])
}
//在此处记录索引以防止重复
索引:=make(映射[int]bool)
//创建n个随机索引
对于i:=0;i
如果集合的总体大小相对较小,或者您正在对集合的很大一部分进行采样,最简单的方法是将元素混洗,然后选择第一个n
:
rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
fmt.Println(a[:5])
如果您不想洗牌整个集合,但改变集合的顺序(或复制整个集合)是可以接受的,那么您可以通过从切片中删除使用的值来更有效地“记录”使用的值
// create a copy of the slice header
c := a
samples := make([]int, n)
for i := 0; i < n; i++ {
r := int(rand.Int63n(int64(len(c))))
samples[i] = c[r]
// remove the sample from the copy slice
c[r], c[len(c)-1] = c[len(c)-1], c[r]
c = c[:len(c)-1]
}
//创建切片头的副本
c:=a
样本:=制造([]整数,n)
对于i:=0;i
如果集合的大小相当大,并且只对一小部分进行采样,则可以通过记录样本索引而不重复它,从原始集合中进行采样,而无需修改。显然,随着样本大小与集合大小之比的增加,碰撞的数量将增加,从而降低效率
例如:
// record indexes here to prevent duplicates
indexes := make(map[int]bool)
// create n random indexes
for i := 0; i < n; i++ {
var r int
for {
r = int(rand.Int63n(int64(len(a))))
if indexes[r] {
continue
}
break
}
indexes[r] = true
}
samples := make([]int, 0, n)
for i := range indexes {
samples = append(samples, a[i])
}
//在此处记录索引以防止重复
索引:=make(映射[int]bool)
//创建n个随机索引
对于i:=0;i
根据样本需要的随机性,我可能会将元素复制到一个映射[T]结构{}
(其中T
是结果类型)和范围
中,以获得我的结果
// assume input is []int
res := make([]int, len(input))
desorted := make(map[int]struct{})
for _, v := range input {
desorted[v] = struct{}
}
i := 0
for k, _ := range desorted {
res[i] = k
i++
}
根据样本需要的随机性,我可能会将元素复制到一个
map[T]struct{}
(其中T
是结果类型)和range
,以获得我的结果
// assume input is []int
res := make([]int, len(input))
desorted := make(map[int]struct{})
for _, v := range input {
desorted[v] = struct{}
}
i := 0
for k, _ := range desorted {
res[i] = k
i++
}
这将修改原始数组,我假设“不替换”意味着原始数组不会被修改。您需要先复制一份。@Zak:“不替换”只意味着同一元素不会被多次采样。不很好地修改原始切片可能是另一个要求,但这里没有指定。好的,很好。TIL@JimB奥巴马对“不替换”的定义是正确的。但是,当a很大时,此解决方案的计算成本很高。@alpaca:您的示例并不大,这使它成为一个合适的解决方案。否则,您可以从原始集合中删除随机样本,或者如果不想修改集合,只需记录样本索引,不重复它们。这将修改原始数组,我假设“不替换”意味着原始数组不会被修改。您需要先复制一份。@Zak:“不替换”只意味着同一元素不会被多次采样。不很好地修改原始切片可能是另一个要求,但这里没有指定。好的,很好。TIL@JimB奥巴马对“不替换”的定义是正确的。但是,当a很大时,此解决方案的计算成本很高。@alpaca:您的示例并不大,这使它成为一个合适的解决方案。否则,您可以从原始集合中删除随机样本,或者如果不想修改集合,只需记录样本索引,而不重复它们。