如何解决如何在python中生成一个范围内的随机数但偏向于某些特定数字?
我想选择一个范围,例如 60 到 80,并从中生成一个随机数。但是,在 65-72 之间我想要更高的概率,而除此之外的其他范围(60-64 和 73 到 80)具有更低的。
示例:
从 60-64
开始,73-80
也有 35% 的机会被选中。来自 65-72
65% 的机会。
子范围中的元素的可能性相同。我正在生成整数。
此外,一个可扩展的解决方案会很有趣,这样人们就可以将其使用范围扩大到更高的范围,例如 1000-2000,但偏向于 1400-1600。
有人可以帮忙提出一些想法吗?
预先感谢任何愿意贡献的人!
解决方法
对于子范围内同样可能的结果,以下方法可以解决问题:
import random
THRESHOLD = [0.65,0.65 + 0.35 * 5 / 13]
def my_distribution():
u = random.random()
if u <= THRESHOLD[0]:
return random.randint(65,72)
elif u <= THRESHOLD[1]:
return random.randint(60,64)
else:
return random.randint(73,80)
这使用统一的随机数来决定您在哪个子范围内,然后在该子范围内生成同样可能的值。
THRESHOLD
值类似于累积分布函数,但其排列方式是首先检查最可能的结果。 65% 的时间 (u <= THRESHOLD[0]
) 您将从范围 [65,72] 生成。否则,剩余的 13 种可能性中有 5 种(35% 的 5/13)在 [60,64] 范围内,其余的在 [73,80] 范围内。 Uniform(0,1) 值 u
将有 65% 的时间低于第一个阈值,如果失败,则有 5/13 的时间低于第二个阈值,高于该阈值的剩余 8/13时间。
结果如下:
,这是一个基于 numpy
的解决方案:
import numpy as np
# Some params
left_start = 60 # Start of left interval====== [60,64]
middle_start = 65 # Start of middle interval === [65,72]
right_start = 73 # Start of right interval ===- [73,80]
right_end = 80 # End of the right interval == [73,80]
count = 1000 # Number of values to generate.
middle_wt = 0.65 # Middle range to be selected with wt/prob=0.65
middle = np.arange(middle_start,right_start)
rest = np.r_[left_start:middle_start,right_start:(right_end+1)]
rng1 = np.random.default_rng(None) # Generator for randomly choosing range.
rng2 = np.random.default_rng(None) # Generator for generating values in the ranges.
# Now generate a random list of 0s and 1s to indicate choice between
# 'middle' and 'rest'. For this number generation we will set middle_wt as
# the weight/probability for 0 and (1-middle_wt) as the weight/probability for 1.
# (0 indicates middle range and 1 indicates the rest.)
range_choices = rng1.choice([0,1],replace=True,size=count,p=[middle_wt,(1-middle_wt)])
# Now generate 'count' values for the middle range
middle_choices = rng2.choice(middle,size=count)
# Now generate 'count' values for the 'rest' of the range (non-middle)
rest_choices = rng2.choice(rest,size=count)
result = np.choose(range_choices,(middle_choices,rest_choices))
print (np.sum((65 <= result) & (result<=72)))
注意:
在上面的代码中,p=[middle_wt,(1-middle_wt)]
是一个权重列表。 middle_wt
是中间范围 [65,72]
的权重,(1-middle_wt)
是其余范围的权重。
输出:
649 # 表示结果的 1000 个值中有 649 个在中间范围 [65,72]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。