微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在python中生成一个范围内的随机数但偏向于某些特定数字?

如何解决如何在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时间。

结果如下:

Histogram of podium

,

这是一个基于 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 举报,一经查实,本站将立刻删除。