Первая точка проста, для второй, я предполагаю, что вы хотите, чтобы «интеграл» freq * x был близок к K (делая каждое x * freq (x) ~ K математически невозможно).Вы можете сделать это, отрегулировав размер выборки.
Первый шаг: целочисленные числа в форме колокольчика между a
и b
, используйте scipy.stats.truncnorm
.Из документов:
Примечания
Стандартная форма этого распределения - стандартная нормаль, усеченная до диапазона [a, b] --- обратите внимание, что a и b определены какдомен стандарт нормальный.Чтобы преобразовать значения клипа для определенного среднего значения и стандартного отклонения, используйте ::
a, b = (myclip_a - my_mean) / my_std, (myclip_b - my_mean) / my_std
Возьмите нормаль в диапазоне -3, 3, чтобы кривая была хорошей.Отрегулируйте среднее значение и стандартное отклонение так, чтобы -3,3 стало a, b:
from scipy.stats import truncnorm
a, b = 10, 200
loc = (a + b) / 2
scale = (b - a) / 6
n = 100
f = truncnorm(-3,3, loc=(a+b)/2,scale=(b-a)/6)
Теперь, поскольку частота связана с функцией плотности вероятности: sum (freq (i) * i) ~ n * sum (pdf (i) * i).Следовательно, n = K / sum (pdf (i) * i).Это можно получить как:
K = 200000
i = np.arange(a, b +1)
n = int(K / i.dot(f.pdf(i)))
Теперь сгенерируйте случайные целочисленные выборки и проверьте функцию:
samples = f.rvs(size=n).astype(np.int)
import matplotlib.pyplot as plt
plt.hist(samples, bins = 20)
print(np.histogram(samples, bins=b-a+1)[0].dot(np.arange(a,b+1)))
>> 200315
![enter image description here](https://i.stack.imgur.com/8vASc.png)