随机选择多选项

时间:2016-01-23 15:20:51

标签: python numpy

我想从一组选项中选择多个项目。每个选项都有自己的一组概率来选择或不选择。

福克斯的例子:
选择,“是”,“否”
“九月”,0.90,0.10 “十月”,0.25,0.75
“十一月”,0.45,0.55
“十二月”,0.50,0.50

“是”表示选项被选中,“否”表示未选中。因此,对于第一次滚动,选择可以是[“九月”,“十二月”],对于第二次滚动,它可以是[“九月”,“十月”,“十一月”]等等。

类似于复选框选项,选择或不选择一个选项与其他选项无关。

我可以通过循环到每个给定的选择中通过numpy.random.choice来完成。但我想知道是否有一种更优雅/更有效的方法来做到这一点?

这就是我做的事情

choices = {
    "September":0.90,
    "October":0.25,
    "November":0.45,
    "December":0.50
}

resp = []
for ch, pr in choices:
    pick = 1
    probs = [pr, 1-pr]
    select = ["yes", "no"]
    choose = numpy.random.choice(select, pick, probs)
    if "yes" in choose[0]:
        resp.append(ch)

感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用numpy.random.uniform函数在[0,1]区间内生成样本。通过将这些与choices中的概率进行比较,您可以创建具有指定概率的随机样本。由于自动广播,每列都与choices的相应概率进行比较。

通过这种方式,您可以创建尺寸为(n_rolls, n_choices)的矩阵,其中n_rolls是您想要重复此次数的次数(如果您只需要一个样本,这可能是1 ),n_choices是不同选择的数量。

import numpy
from collections import OrderedDict

choices = OrderedDict()
choices["September"] = 0.90
choices["October"] = 0.25
choices["November"] = 0.45
choices["December"] = 0.50

n_rolls = 5
probs = numpy.random.uniform(size=(n_rolls, len(choices)))
samples = probs < choices.values()

结果将是一个bool数组,其中每列对应一个来自choices的选项,每行包含一次尝试。当我们使用OrderedDict时,结果的排序方式与输入字典数据的方式相同。

>>> samples
array([[False, False, False, False],
       [ True,  True,  True, False],
       [ True, False, False, False],
       [ True, False,  True,  True],
       [ True, False,  True, False]], dtype=bool)

作为测试:让我们找到n_rolls=1000000的每列的概率:

>>> numpy.mean(samples, axis=0)
array([ 0.899713,  0.249405,  0.449437,  0.499881])

要将此结果转换为与您指定的列表类似的列表,您可以使用numpy.wherenumpy.choose的组合:

res = numpy.choose(numpy.where(samples[0, :]), choices.keys())

print samples[0,:],'\n',res
[ True False  True  True] 
[['September' 'November' 'December']]

不幸的是,这部分仅适用于单行,因此如果您有多个卷,则需要在循环中执行此最后一步。