How to incrementally sample without replacement?

前端 未结 13 1603
别跟我提以往
别跟我提以往 2020-12-05 00:38

Python has my_sample = random.sample(range(100), 10) to randomly sample without replacement from [0, 100).

Suppose I have sampled n

相关标签:
13条回答
  • 2020-12-05 01:27

    Here's a way that doesn't build the difference set explicitly. But it does use a form of @Veedrac's "accept/reject" logic. If you're not willing to mutate the base sequence as you go along, I'm afraid that's unavoidable:

    def sample(n, base, forbidden):
        # base is iterable, forbidden is a set.
        # Every element of forbidden must be in base.
        # forbidden is updated.
        from random import random
        nusable = len(base) - len(forbidden)
        assert nusable >= n
        result = []
        if n == 0:
            return result
        for elt in base:
            if elt in forbidden:
                continue
            if nusable * random() < n:
                result.append(elt)
                forbidden.add(elt)
                n -= 1
                if n == 0:
                    return result
            nusable -= 1
        assert False, "oops!"
    

    Here's a little driver:

    base = list(range(100))
    forbidden = set()
    for i in range(10):
        print sample(10, base, forbidden)
    
    0 讨论(0)
提交回复
热议问题