Существует ли распределение случайных чисел, которое подчиняется Закону Бенфорда?

Python имеет несколько способов генерации различных распределений случайных чисел, см. Документацию для random модуля . К сожалению, они не очень понятны без соответствующего математического фона, особенно учитывая требуемые параметры.

Я хотел бы знать, способны ли какие-либо из этих методов создавать случайные числа с распределением, которое подчиняется Закону Бенфорда и какие значения параметров являются подходящими. А именно для совокупности целых чисел эти целые числа должны начинаться с «1» около 30% времени, «2» около 18% времени и т. Д.


Используя ответ Яна Дворкака, я собрал следующий код и, похоже, работает отлично.

 def benfords_range_gen(stop, n): """ A generator that returns n random integers between 1 and stop-1 and whose distribution meets Benford's Law ie is logarithmic. """ multiplier = math.log(stop) for i in range(n): yield int(math.exp(multiplier * random.random())) >>> from collections import Counter >>> Counter(str(i)[0] for i in benfords_range_gen(10000, 1000000)) Counter({'1': 300696, '2': 176142, '3': 124577, '4': 96756, '5': 79260, '6': 67413, '7': 58052, '8': 51308, '9': 45796}) 

2 Solutions collect form web for “Существует ли распределение случайных чисел, которое подчиняется Закону Бенфорда?”

Закон Бенфорда описывает распределение первых цифр набора чисел, если числа выбраны из широкого диапазона в логарифмическом масштабе. Если вы подготовите логарифмическое распределение в течение одного десятилетия, оно будет уважать и закон. 10^[0,1) будет производить это распределение.

Это даст желаемое распределение: math.floor(10**random.random())

Просто играю.

Гораздо более неэффективная, но, возможно, более заметная реализация для тех, как я, которые не настолько склонны математике …

Простым способом создания любого желаемого дистрибутива является заполнение списка желаемыми процентами элемента, а затем использование random.choice(<list>) , так как это возвращает единый выбор элементов в списке.

 import random probs = [30.1, 17.6, 12.5, 9.7, 7.9, 6.7, 5.8, 5.1, 4.6] nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] population = sum([[n] * int(p * 10) for n, p in zip(nums, probs)], []) max_value = 100 min_value = 1 result_pop = [] target_pop_size = 1000 while len(result_pop) < target_pop_size: s = str(random.choice(population)) while True: r = random.randint(min_value, max_value) if str(r).startswith(s): break result_pop.append(r) 
  • Pyautogui: Движение мыши с кривой Безье
  • Как указать верхний и нижний пределы при использовании numpy.random.normal
  • Генерация «случайной» строки из другой строки в python?
  • Правильный способ генерации случайных чисел в Cython?
  • Как я могу создать произвольный генератор кода hexdigit с использованием .join и для циклов?
  • Генерирование случайных векторов евклидовой нормы <= 1 в Python?
  • Создание случайной буквы в Python
  • Ненужный случайный выбор кортежей
  • Python. Как я могу рандомизировать вопросы, содержащие A, B, C, D
  • Как сгенерировать уникальные 64-битные целые числа из Python?
  • Как создать случайный UUID, который воспроизводится (с семенем) в Python
  • Python - лучший язык программирования в мире.