当平均值已知时,Python中的随机数生成器

时间:2019-03-29 10:51:14

标签: python random

在Python中,我试图获取[0,100]之间的均值25的10个随机数的列表。我所拥有的所有信息如下。

Total = 250
Number_of_users = 10
Average_score = 25

过去,我随机使用高斯函数,但没有标准偏差,所以我有点卡住。还有另一种方法吗?

我的输出将类似于:

[20, 30, 18, 21, 27, 30, 15, 24, 31, 30]

4 个答案:

答案 0 :(得分:2)

好吧,如果您想要if possible the total would be 250 as well,那么答案将是从Multinomial Distribution中抽样。根据定义,它将产生总计为250且平均值为25的随机值。如果该数字之一超过100(这将非常少见),我们将玩接受/拒绝游戏。在NumPy的帮助下

import numpy as np

Total = 250
Number_of_users = 10
Average_score = 25
Upper_boundary = 100

probs = np.full(10, 1.0/np.float64(Number_of_users), dtype=np.float64) # probabilities

N = 10000 # samples to test
k = 0
while k < N:
    q = np.random.multinomial(Total, probs)
    t = np.where(q > Upper_boundary) # check for out-of boundaries
    if np.any(t):
        print("Rejected, out of boundaries") # reject, do another sample
        continue
    # accepted
    # do something with q, print((sum(q), len(q), np.mean(q)))

    k += 1

答案 1 :(得分:1)

我有一个想法:

import random

Number_of_users = 10
Average_score = 25

index = Number_of_users / 2
result = []

while index:
    index -= 1
    random_number = random.randint(0,51)
    result.append(random_number)
    result.append(50-random_number)

print (result)
print (sum(result))

您将获得5对随机数;对于每对随机数,第一个随机产生于0〜50之间,而第二个则取决于第一个随机数。

我的方法的一个缺点是,它不能处理奇数个随机数。

答案 2 :(得分:1)

这是两个约束:

  1. 数字是随机的

  2. 均值收敛到25

由于对分布没有限制,因此可以通过从2种不同的均匀分布中进行采样来实现此目的:

import random
out_list = []
for i in range(1,10):
    random_number = random.uniform(0,1)
    if random_number < 0.75:
        # Append uniform random number between 0 - 25 with probability .75
        out_list.append(random.randint(0,25))
    else:
        #Append uniform random number between 0-75 with probability 0.25
        out_list.append(random.randint(25,100))

print(out_list)
import statistics
print(statistics.mean(out_list))

此外,该问题可能会在stats.stackexchange.com中找到更好的地方。

答案 3 :(得分:0)

您可以尝试使用平均值为25的beta分布,即选择a,b参数,使a /(a + b)= 0.25。您可以在下图中通过更改a,b参数来了解所需的方差。 enter image description here

from scipy.stats import beta
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(3, sharex=True, figsize=(7,7))

x = np.linspace(0,1,100)
a = [ 2.5,10, 25]
b = [ 7.5,30, 75]

for i in range(len(ax)):
    ax[i].plot(x,beta.pdf(x,a[i],b[i]))
    ax[i].text(0.75,0.75,"a={}, b={}".format(a[i],b[i]), transform=ax[i].transAxes)

plt.show()
result = list(map(int, 100*beta.rvs(10,30,size=9))) #to be more precise, need to check that these 9 values fall below 250
result.append(250-sum(result))
print("10 samples from a Beta(10,30) distribution:\n ",*result)



Out: 10 samples from a Beta(10,30) distribution:
  20 25 21 20 31 28 24 29 23 29