random.randint 的加权版本
A weighted version of random.randint
我想在a
和b
之间随机选择一个整数(均包含),统计权重为c
。
c
是介于 a
和 b
之间的值。
将权重因子 c
应用于 random.randint 的最有效方法是什么?
我得到的最接近的是this问题,但有很大的不同:
我只有一个统计权重c
,不是a
和b
之间每个值的统计概率。
示例:
a = 890
b = 3200
c = 2600
print(random.randint(a,b))
>>>> supposed to result most frequently in a value around 2600
我不太关心a
和b
之间的分布,只要c
上有权重就行。然而,高斯分布将不胜感激。
请注意:此问题不解决numpy.random
模块,如问题。
您使用
random.choices(range(a,b+1), weights= [....], k=1) # or cum_weights
k
为 1,人口在 range(a,b+1)
和您想要的权重。
参见:https://docs.python.org/3/library/random.html#random.choices
你必须计算一个可能的(任意)权重,f.e.:
import random
from collections import defaultdict
a = 8
b = 32
c = 26
# hacked distribution
w = [(i-a)**2 if i <= c else (b-i+a)**2 for i in range(a,b+1)]
d=defaultdict(int)
for i in range(a,b+1):
d[i]=0
# test for 10k numbers
for num in random.choices(range(a,b+1), weights = w, k=10000):
d[num] += 1
print(w)
print(d)
还是随机的,一个运行得到了我:
# hacked distribution
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
256, 289, 196, 169, 144, 121, 100, 81, 64]
# test for 10k numbers
{8: 0, 9: 8, 10: 7, 11: 37, 12: 61, 13: 94, 14: 149, 15: 175, 16: 229,
17: 283, 18: 374, 19: 450, 20: 493, 21: 628, 22: 672, 23: 820, 24: 907,
25: 1038, 26: 1183, 27: 564, 28: 537, 29: 435, 30: 325, 31: 293, 32: 238}
听起来 triangular distribution 可能符合您的需要。 a
和b
分别是min和max,c
对应分布的模式(最可能的结果)。
numpy.random
中有一个三角发电机。它生成浮点数,但您可以舍入然后对结果进行整数化。如果你很挑剔,这会稍微偏离最小值和最大值,与其他整数值相比,它们只有一半的范围,因此只有一半的预期计数。统计学家使用 连续性校正 调整从实数到整数的范围转换:从最小值减去 1/2,将 1/2 添加到最大值。如果您处理的是小范围,这很可能是相关的,如下面的小示例所示。
import numpy as np
import matplotlib.pyplot as plt
# replace with your actual values
a = 1
b = 5
c = 2
# Without continuity correction
plt.hist(np.ma.round(np.random.triangular(
left = a,
mode = c,
right = b,
size = 100000)
).astype(int),
range = (0.5, 5.5), bins = 50, density = True)
plt.show()
# With continuity correction
plt.hist(np.ma.round(np.random.triangular(
left = a - 0.5,
mode = c,
right = b + 0.5,
size = 100000)
).astype(int),
range = (0.5, 5.5), bins = 50, density = True)
plt.show()
以下是您实际参数化后的结果:
# Actual target case
a = 890
b = 3200
c = 2600
plt.hist(np.ma.round(np.random.triangular(
left = a - 0.5,
mode = c,
right = b + 0.5,
size = 100000)
).astype(int),
range = (500, 3500), bins = 300, density = True)
plt.show()
请注意,与评论中建议的正态分布不同,这保证在 (a, b)
.
范围内
我想在a
和b
之间随机选择一个整数(均包含),统计权重为c
。
c
是介于 a
和 b
之间的值。
将权重因子 c
应用于 random.randint 的最有效方法是什么?
我得到的最接近的是this问题,但有很大的不同:
我只有一个统计权重c
,不是a
和b
之间每个值的统计概率。
示例:
a = 890
b = 3200
c = 2600
print(random.randint(a,b))
>>>> supposed to result most frequently in a value around 2600
我不太关心a
和b
之间的分布,只要c
上有权重就行。然而,高斯分布将不胜感激。
请注意:此问题不解决numpy.random
模块,如
您使用
random.choices(range(a,b+1), weights= [....], k=1) # or cum_weights
k
为 1,人口在 range(a,b+1)
和您想要的权重。
参见:https://docs.python.org/3/library/random.html#random.choices
你必须计算一个可能的(任意)权重,f.e.:
import random
from collections import defaultdict
a = 8
b = 32
c = 26
# hacked distribution
w = [(i-a)**2 if i <= c else (b-i+a)**2 for i in range(a,b+1)]
d=defaultdict(int)
for i in range(a,b+1):
d[i]=0
# test for 10k numbers
for num in random.choices(range(a,b+1), weights = w, k=10000):
d[num] += 1
print(w)
print(d)
还是随机的,一个运行得到了我:
# hacked distribution
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225,
256, 289, 196, 169, 144, 121, 100, 81, 64]
# test for 10k numbers
{8: 0, 9: 8, 10: 7, 11: 37, 12: 61, 13: 94, 14: 149, 15: 175, 16: 229,
17: 283, 18: 374, 19: 450, 20: 493, 21: 628, 22: 672, 23: 820, 24: 907,
25: 1038, 26: 1183, 27: 564, 28: 537, 29: 435, 30: 325, 31: 293, 32: 238}
听起来 triangular distribution 可能符合您的需要。 a
和b
分别是min和max,c
对应分布的模式(最可能的结果)。
numpy.random
中有一个三角发电机。它生成浮点数,但您可以舍入然后对结果进行整数化。如果你很挑剔,这会稍微偏离最小值和最大值,与其他整数值相比,它们只有一半的范围,因此只有一半的预期计数。统计学家使用 连续性校正 调整从实数到整数的范围转换:从最小值减去 1/2,将 1/2 添加到最大值。如果您处理的是小范围,这很可能是相关的,如下面的小示例所示。
import numpy as np
import matplotlib.pyplot as plt
# replace with your actual values
a = 1
b = 5
c = 2
# Without continuity correction
plt.hist(np.ma.round(np.random.triangular(
left = a,
mode = c,
right = b,
size = 100000)
).astype(int),
range = (0.5, 5.5), bins = 50, density = True)
plt.show()
# With continuity correction
plt.hist(np.ma.round(np.random.triangular(
left = a - 0.5,
mode = c,
right = b + 0.5,
size = 100000)
).astype(int),
range = (0.5, 5.5), bins = 50, density = True)
plt.show()
以下是您实际参数化后的结果:
# Actual target case
a = 890
b = 3200
c = 2600
plt.hist(np.ma.round(np.random.triangular(
left = a - 0.5,
mode = c,
right = b + 0.5,
size = 100000)
).astype(int),
range = (500, 3500), bins = 300, density = True)
plt.show()
请注意,与评论中建议的正态分布不同,这保证在 (a, b)
.