Похоже, вы хотите сгенерировать данные на основе PDF, описанного во второй таблице. PDF - это что-то вроде
0 for x <= B
A*exp(-A*(x-B)) for x > B
A
определяет ширину вашего распределения, которая всегда будет нормализована, чтобы иметь область 1. B
- это горизонтальное смещение, которое в вашем случае равно нулю , Вы можете сделать это целочисленным распределением, связав с помощью ceil
.
CDF нормализованной убывающей экспоненты 1 - exp(-A*(x-B))
. Как правило, простой способ создать пользовательский дистрибутив - это сгенерировать одинаковые числа и отобразить их через CDF.
К счастью, вам не придется этого делать, поскольку scipy.stats.expon
уже обеспечивает реализацию, которую вы ищете. Все, что вам нужно сделать, это вписаться в данные в вашем последнем столбце, чтобы получить A
(B
явно равен нулю). Вы можете легко сделать это с помощью curve_fit
. Помните, что A
отображается на 1.0/scale
на языке scipy.
Вот пример кода. Я добавил дополнительный уровень сложности, рассчитав интеграл целевой функции от n-1
до n
для целочисленных входов, принимая во внимание биннинг для вас при выполнении подбора.
import numpy as np
from scipy.optimize import curve_fit
from scipy.stats import expon
def model(x, a):
return np.exp(-a * (x - 1)) - exp(-a * x)
#Alternnative:
# return -np.diff(np.exp(-a * np.concatenate(([x[0] - 1], x))))
x = np.arange(1, 16)
p = np.array([0.8815, 0.0755, ..., 0.0010, 0.0005])
a = curve_fit(model, x, p, 0.01)
samples = np.ceil(expon.rvs(scale=1/a, size=2000)).astype(int)
samples[samples == 0] = 1
data = np.bincount(samples)[1:]