Вы знаете, я много чего перепробовал и таки нашёл ответ, который, хоть и математически не совсем соответствует моим запросам, но тем не менее, поставленную задачу решает. Пусть кому-то это покажется костыльным велосипедом, но это работает быстрее и, конечно, не напрягает мою память. Это решение не прямолинейное. А математику решения можно и подкорректировать и теперь, если у меня намертво зависал ноутбук, то сейчас я вызываю функцию в цикле с 1000 итерациями и код у меня выполняется примерно за секунду.
Вот сам метод:
def get_job_dist():
numbers = '0,1,2,3,4,5,6,7,8,9'
weights = np.arange(1, 11, 1.0)
weights = [1/x for x in weights]
numbers = numbers.split(',')
steps = np.arange(2,6)
steps_w = [1/x for x in steps]
steps_w /= sum(steps_w)
weights /= sum(weights)
steps_count = np.random.choice(steps, 1, p= steps_w)
steps_count = steps_count[0]
dist_str_arr = np.random.choice(numbers, steps_count, p = weights)
dist_str = ''
step = 0
for sym in dist_str_arr:
if int(sym) < 2 and step < 2 and steps_count < 3:
dist_str += str(randint(2,9))
else:
dist_str += sym
step += 1
dist = int(dist_str)
if dist < 20:
dist += randint(20, 99)
return dist