【问题标题】:Mimicking random.sample() for non-uniform distributions为非均匀分布模仿 random.sample()
【发布时间】:2017-12-27 20:00:25
【问题描述】:

我想在 python 中模拟random.sample() 的功能,但是选择的分布不均匀(在这种情况下是三角形)。对此很重要的是,单个项目不会被选择两次(如 random.sample docs 中所述)。这是我所拥有的:

...

def tri_sample(population, k, mode=0):
    """
    Mimics the functionality of random.sample() but with a triangular
    distribution over the length of the sequence.

    Mode defaults to 0, which favors lower indices.
    """
    psize = len(population)
    if k > psize:
        raise ValueError("k must be less than the number of items in population.")
    if mode > psize:
        raise ValueError("mode must be less than the number of items in population.")
    indices_chosen = []
    sample = []
    for i in range(k):
        # This ensures unique selections
        while True:
            choice = math.floor(random.triangular(0, psize, mode))
            if choice not in indices_chosen:
                break
        indices_chosen.append(choice)
        sample.append(population[choice])
    return sample

...

我怀疑这不是防止重复项目被拉出的理想方法。设计时我的第一个想法是复制population.pop() 的项目,因为它们被抽样以防止选择相同的项目两次,但我发现了两个问题:

  1. 如果population 是一个对象列表,则在复制该列表同时仍确保sample 中的项目指向population 中的相同对象时可能会遇到一些困难。
  2. 在总体上使用.pop() 会改变总体规模,每次都会改变分布。理想情况下,无论以何种顺序选择项目,分布(不确定我是否正确使用了该术语 - 每个项目被调用的概率)都是相同的。

有没有更有效的方法从总体中抽取非均匀随机样本?

【问题讨论】:

    标签: python random probability


    【解决方案1】:

    你可以通过numpy.random.choice实现你想要的

    这个函数的输入如下:

    numpy.random.choice(a, size=None, replace=True, p=None)
    

    因此您可以将权重向量p 指定为您想要的概率分布,并选择replace=False,这样样本就不会重复。

    或者,您可以使用numpy.random.triangular 直接从三角分布中采样。您可以在循环中执行此操作,并且仅当新结果未出现在列表中时才将其添加到列表中。

    【讨论】:

      猜你喜欢
      • 2011-04-04
      • 2018-02-06
      • 2011-03-02
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 1970-01-01
      相关资源
      最近更新 更多