在Python中从固定元素集合中快速抽样

10 投票
3 回答
3121 浏览
提问于 2025-04-17 04:35

我需要从一个固定大小的数字集合中随机抽取一个数字,进行一些计算,然后把新的数字放回集合里。(我需要抽取的数字数量非常多)

我试过把数字存储在一个列表里,然后用 random.choice() 来选择一个元素,取出它,再把新的元素加进去。但是这样太慢了!

我在考虑把数字存储在一个 numpy 数组中,随机抽取一些索引,然后对每个索引进行计算。

  • 有没有更快的方法来完成这个过程?

3 个回答

2

random.sample( 一个集合、列表或Numpy数组, Nsample ) 这个方法非常快, 但我不太清楚你想要的是否是这样的:

import random

Setsize = 10000
Samplesize = 100
Max = 1 << 20
bigset = set( random.sample( xrange(Max), Setsize ))  # initial subset of 0 .. Max

def calc( aset ):
    return set( x + 1 for x in aset )  # << your code here

    # sample, calc a new subset of bigset, add it --
for iter in range(3):
    asample = random.sample( bigset, Samplesize )
    newset = calc( asample )  # new subset of 0 .. Max
    bigset |= newset

你可以使用Numpy数组 或者bitarray 来代替set,不过我觉得在calc()这个函数里的计算时间会占大头。

你的集合大小和样本大小大概是多少呢?

4

我需要从一个固定大小的集合中随机抽取一个数字,进行一些计算,然后把新的数字放回这个集合里。

s = list(someset)           # store the set as a list
while 1:
    i = randrange(len(s))   # choose a random element
    x = s[i]
    y = your_calculation(x) # do some calculation
    s[i] = y                # put the new number back into the set
7

在Python中,列表其实是用数组来实现的(就像Java的 ArrayList 和C++的 std::vector)。所以,如果你想从中间删除一个元素,这个过程会比较慢,因为后面的所有元素都得重新调整位置。想了解更多可以看看这个链接:http://www.laurentluce.com/posts/python-list-implementation/。如果你不太在意元素的顺序,我建议你可以用 random.randint(0, len(L) - 1) 来随机选择一个索引 i,然后用 L[i] = calculation(L[i]) 来更新第 i 个元素。

撰写回答