douhui9192 2018-06-14 21:58

# 加权采样，无需使用gonum进行替换

I have a big array of items and another array of weights of the same size. I would like to sample without replacement from the first array based on the weights from the second array. Is there a way to do this using `gonum`?

• 写回答

#### 1条回答默认 最新

• dpndp64206 2018-06-14 22:54
关注

`Weighted` and its relative method `.Take()` look exactly like what you want.

From the doc:

``````func NewWeighted(w []float64, src *rand.Rand) Weighted
``````

`NewWeighted` returns a `Weighted` for the weights `w`. If `src` is `nil`, `rand.Rand` is used as the random source. Note that sampling from weights with a high variance or overall low absolute value sum may result in problems with numerical stability.

``````func (s Weighted) Take() (idx int, ok bool)
``````

`Take` returns an index from the Weighted with probability proportional to the weight of the item. The weight of the item is then set to zero. `Take` returns `false` if there are no items remaining.

Therefore `Take` is indeed what you need for sampling without replacement.

You can use `NewWeighted` to create a `Weighted` with the given weights, then use `Take` to extract one index with probability based on the previously set weights, and then select the item at the extracted index from your array of samples.

Working example:

``````package main

import (
"fmt"
"time"

"golang.org/x/exp/rand"

"gonum.org/v1/gonum/stat/sampleuv"
)

func main() {
samples := []string{"hello", "world", "what's", "going", "on?"}
weights := []float64{1.0, 0.55, 1.23, 1, 0.002}

w := sampleuv.NewWeighted(
weights,
rand.New(rand.NewSource(uint64(time.Now().UnixNano())))
)

i, _ := w.Take()

fmt.Println(samples[i])
}
``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥20 C语言字符串不区分大小写字典排序相关问题
• ¥15 关于#python#的问题：我希望通过逆向技术爬取1688搜索页下滑加载的数据
• ¥15 学习C++过程中遇到的问题
• ¥15 关于Linux的终端里，模拟实现一个带口令保护的屏保程序遇到的输入输出的问题！(语言-c语言)
• ¥15 学习C++过程中遇到的问题
• ¥15 请问，这个嵌入式Linux系统怎么分析，crc检验区域在哪
• ¥15 二分类改为多分类问题