蓄水池算法简介

本文介绍了一种名为水库采样的算法,该算法可在不确定总数的情况下,从大量数据中按概率抽取固定数量的样本。通过实现该算法,我们展示了如何在Python中使用随机数生成器来完成这一任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从N个元素中随机抽取k个元素,但是N不定。每个元素抽取的概率是k/N。
解答:先选中前k个,从k+1到最后一个元素,以1/i (i = k+1, k+2, ... N)的概率选中第i个元素,并且随机替换一个原来选中的元素。

'''
 Reservoir Sampling implementation
'''
from random import Random

def RandomSelect(knum, rand=None):
    ''' (int, func) -> list

    Reservoir Sampling implementation
    >>> myList = [1,2,3,4,5,6,7,8,-1] 
    >>> ge = RandomSelect(3)
    >>> ge.next()
    >>> for v in myList:
            cr.send(v)
    '''
    selection = None
    k_elems_list = []
    count = 0
    if rand is None:
        rand = Random()
    while True:
        item = yield selection
        if item == -1:
            break
        if len(k_elems_list) < knum:
            k_elems_list.append(item)
        elif rand.randint(0, count) == 0:
            index = rand.randint(0, knum-1)
            k_elems_list.pop(index)
            k_elems_list.insert(index, item)
        count += 1
    print k_elems_list

if __name__ == '__main__':
    myList = [1,2,3,4,5,6,7,8,-1]
    cr = RandomSelect(3);
    cr.next() # advance to the yield statement, otherwise I can't call send
    try:
        for val in myList:
            cr.send(val)
    except StopIteration:
        pass
    finally:
        del cr



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值