【问题标题】:Generating random numbers with weighted probabilities in python在python中生成具有加权概率的随机数
【发布时间】:2016-04-26 12:57:10
【问题描述】:

给定一个正整数数组a,目标是根据它们在数组中的权重生成 5 个随机数。

例如:

a = [2,3,4,4,4,4,4,6,7,8,9]

在这种情况下,数字 4 出现了 5 次,在这种情况下,数字 4 应该有 5/11 的概率出现。

数字不应重复。

【问题讨论】:

  • 不重复是什么意思?在那个罐子里,它不会保留重量。你的意思是不重复索引?
  • 你的问题不是很清楚,但如果你的意思是我认为你的意思,这里是重复的:stackoverflow.com/questions/10803135/…
  • 你在np.random.choice(list(set(a)), size=5,replace=False)之后吗?
  • 通过执行 list(set(a)) 您正在删除权重。问题是我没有计算权重,因为他们在stackoverflow.com/questions/10803135/… 上拥有它我的权重是重复的数字@ajcr 你是对的,但我没有每个值的概率
  • @Charlie:啊我明白了,所以给定a,你想计算权重然后使用随机选择函数吗?

标签: python arrays numpy probability


【解决方案1】:

给定a,一个正整数数组,您首先需要计算每个整数的频率。例如,使用bincount:

>>> a = [2,3,4,4,4,4,4,4,5,6,7,8,9,4,9,2,3,6,3,1]
>>> b = np.bincount(a)

b 告诉您a 中每个整数的频率。因此,相应的权重集是数组b/len(a)。将np.random.choice 与这些权重一起使用,replace=False 应该可以满足您的需求:

>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([5, 9, 4, 3, 8])
>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([7, 4, 6, 9, 1])
>>> np.random.choice(np.arange(len(b)), 5, p=b/len(a), replace=False)
array([3, 7, 4, 9, 6])

如果您不只使用正整数,或者如果您正在使用大正整数,@user2357112 在下面的 cmets 中指出 np.unique 提供了另一种解决方案。在这里你会写:

>>> choices, counts = np.unique(a, return_counts=True)
>>> np.random.choice(choices, 5, p=counts/len(a), replace=False)
array([9, 8, 2, 4, 5])

【讨论】:

  • 您还可以将numpy.uniquereturn_counts 选项一起使用,当您的输入不是一堆非负整数或max(a) 很大时效果会更好。
  • 谢谢 - 我似乎总是忘记 return_counts 参数 - 在你提到的情况下确实会好得多。
  • 可以更新到这个例子吗? a =[(23, 11), (10, 16), (13, 11), (12, 3), (4, 15), (10, 16), (10, 16)] b = Counter(elem对于 a) 中的元素 c = len(a) @ajcr
  • @Charlie:我认为您更新的问题足以保证提出一个全新的问题(整数列表与以元组为键的 Counter 对象)。最好离开 this 页面来了解整数列表,因为这可能是最常见的情况,并且可能对未来的读者有所帮助。如果您提出有关 Counter 对象的新问题,我很乐意查看并尽我所能回答。
  • @ajcr 我已经更新了问题,这是另一个问题(stackoverflow.com/questions/34934540/…)顺便说一句谢谢!!!
【解决方案2】:

您可能正在寻找numpy.random.multinomial 例如np.random.multinomial(1, [1/6.]*6, size=1) 正在掷一次公平的骰子。 得到结果后,您可以根据需要更新概率向量(必须总和为 1)。例如numpy.random.multinomial(1, [1/2., 1/2., 0., 0., 0., 0.], size=1)

【讨论】:

    【解决方案3】:

    最简单的解决方案(也许效率最低)如下:

    import random
    def get_randoms(n, a):
        a = a[:]
        r = []
        for i in range(n):
            r.append(random.choice(a))
            a = [y for y in a if y != r[-1]]
        return r
    
    print get_randoms(5, [2,3,4,4,4,4,4,4,5,6,7,8,9,4,9,2,3,6,3,1])
    

    输出可能类似于

    [8, 2, 3, 6, 9]
    

    【讨论】:

      猜你喜欢
      • 2013-07-10
      • 2012-02-11
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2012-12-04
      相关资源
      最近更新 更多