Python生成随机字符串

3
我有一个单词列表。
count=100    
list = ['apple','orange','mango']

使用随机函数对上述计数,是否可以使40%的时间选择苹果,30%的时间选择橙子,30%的时间选择芒果?

例如:

for the count=100, 40 times apple, 30 times orange and 30 times mango.

这个选择必须是随机的

2个回答

5
根据对关于生成具有指定权重的离散随机变量的问题的回答(参见链接),您可以使用numpy.random.choice,它比random.choice的代码运行速度快20倍。
from numpy.random import choice

sample = choice(['apple','orange','mango'], p=[0.4, 0.3, 0.3], size=1000000)

from collections import Counter
print(Counter(sample))

输出:

Counter({'apple': 399778, 'orange': 300317, 'mango': 299905})

更不用说,它比“按所需比例构建列表,然后对其进行混洗”还要容易实现。此外,混洗总是会产生恰好40%的苹果、30%的橙子和30%的芒果,这并不等于说“根据离散概率分布生成一百万个水果的样本”。后者正是两种choice解决方案(以及bisect)所做的。如上所示,使用numpy时大约有40%的苹果等等。

4
最简单的方法是按所需比例构建一个列表,然后进行洗牌。
>>> import random
>>> result = ['apple'] * 40 + ['orange'] * 30 + ['mango'] * 30
>>> random.shuffle(result)

根据新要求,计数确实为1,000,000:

>>> count = 1000000
>>> pool = ['apple'] * 4 + ['orange'] * 3 + ['mango'] * 3
>>> for i in xrange(count):
        print random.choice(pool)

一种更加通用但速度较慢的方法是使用bisect累积分布函数进行插值:

>>> import bisect
>>> choices = ['apple', 'orange', 'mango']
>>> cum_prob_dist = [0.4, 0.7]
>>> for i in xrange(count):
        print choices[bisect.bisect(cum_prob_dist, random.random())]

但是如果计数=1000000,那么列表大小将会增加,实际上我正在尝试模拟一个数据集,每天有1000000行,在一个月的时间内,如果我使用相同的逻辑,这样做是否好? - Maverick
这个概念非常通用,有很多方法可以在其基础上进行构建。我编辑了答案,展示如何使用random.choice()从池中逐个选择元素,使得它们的比例正确。你也可以制作一个累积分布,并使用bisect进行选择,但对于你描述的问题来说,那可能有些过度设计了。 - Raymond Hettinger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接