我有一个清单:
a = [1,2,1,1,3,5,6,2]
我想从此列表中随机选择3个元素,但它们必须全部不同。
我需要保持“体重”。因此,每个元素都不可能从集合(a)中进行采样。
到目前为止,我的解决方案是:
while condition == False:
mysample = random.sample(a, 3)
if len(set(mysample)) - len(mysample) !=0:
condition = False
else:
condition = True
但是这迫使我重新抽样,因为元素都要与众不同。这适用于小样本,但对于大样本,我的代码变得非常低效......
答案 0 :(得分:3)
你可以随机播放前三个非重复元素:
import random
random.shuffle(your_list)
three_elements = set()
for v in your_list:
if len(three_elements) == 3: break
three_elements.add(v)
答案 1 :(得分:1)
l = []
seen = set()
while len(l) < 3:
ch = choice(a)
if ch not in seen:
l.append(ch)
seen.add(ch)
print(l)
根据实际不同数字与元素的比例,不同的方法将具有不同的优势:
In [7]: a = [choice(range(10000)) for _ in range(100000)]
In [6]: import random
In [7]: a = [choice(range(10000)) for _ in range(100000)]
In [8]: %%timeit
random.shuffle(a)
three_elements = set()
for v in a:
if len(three_elements) == 5000:
break
if not v in three_elements:
three_elements.add(v)
...:
10 loops, best of 3: 36.5 ms per loop
In [9]: %%timeit
l = []
seen = set()
while len(l) < 5000:
ch = choice(a)
if ch not in seen:
l.append(ch)
seen.add(ch)
...:
100 loops, best of 3: 5.16 ms per loop
10分钟后运行你的代码我不得不退出这个过程,因为无论你选择什么,都将是一个重大改进。
如果重复比例与列表中的实际项目有较大比例,并且您希望样本量非常大,那么使用随机播放会更有效率,否则改组成本会降低效率,而不是简单地使用集合和选择,
答案 2 :(得分:0)
while count < sampleSize: # where sampeSize is the number of values you want
s = random.sample(a, 1)
filter(lambda x: x != s, a)
mysample.append(s)
count += 1
答案 3 :(得分:0)
这可能比必要的更复杂,但这是一个使用reservoir sampling的修改版本的实现。
import itertools
import random
def element_at(iterable, index, default=None):
return next(itertools.islice(iterable, index, None), default)
def sample_unique(iterable, size):
S = set()
for index, item in enumerate(iterable):
if len(S) < size:
S.add(item)
else:
r = random.randint(0, index)
if r < size:
other = element_at(S, r)
if item not in S:
S.remove(other)
S.add(item)
return S