В Python с numpy, как получить равномерно распределенные случайные числа с плавающей запятой между 0 и натуральным x, включая оба?

В Python с numpy для заданного натурального числа x мы хотели бы получить массив (скажем, 20×2 или любую другую форму) равномерно распределенных чисел с плавающей запятой в интервале [0,x]. Обратите внимание, что интервал закрыт.

Судя по http://stackoverflow.com/a/33359758, совершенно испорченный подход

x=10
print(np.reshape([int.from_bytes(os.urandom(8))*x/((1<<64)-1) for i in range(40)],(20,2)))

Однако результаты зависят от операционной системы. Я также не понимаю, могут ли полученные числа распределяться равномерно и почему.

Обратите внимание, что (другой) подход, заключающийся в том, чтобы каким-то образом получить унифицированные числа с плавающей запятой IEEE 754 из [0,1] и затем умножить их на x, потенциально ошибочен, потому что, если x не является степенью 2, ваши числители (с точки зрения представления как числитель * 2^{…}) всегда будет кратен x, тогда как все значения, не кратные x, никогда не появятся.

Любая помощь? Подойдут и псевдослучайные числа (при условии, что они распределены равномерно).

Вы также можете предположить, что x мало, скажем, x<2^8, если это поможет.

Из любопытства, зачем вам верхний диапазон?

Andrew Yim 27.06.2024 17:05

Ваш вопрос требует пояснения. С математической точки зрения использование открытого или закрытого интервала не имеет никакого значения, поскольку вероятность получить любое действительное число, включая границы, равна 0. Это может иметь значение, если вы можете сгенерировать только конечное число случайных чисел в этом интервале. Теперь от того, как вы генерируете эти числа, будет зависеть, возможно ли получить границы и какова будет вероятность их получения, и это должен быть ваш выбор. Но, как уже спрашивалось: почему именно это будет актуально?

Thierry Lathuille 27.06.2024 17:10

@AndrewYim Ничего особенного. Иногда вы видите закрытые интервалы в исходной задаче (от вашего учителя/начальника/клиента), что затем приводит к минимальной задаче.

AlMa1r 27.06.2024 17:10

@ThierryLathuille В [0,x] существует только конечное число чисел с плавающей запятой IEEE.

AlMa1r 27.06.2024 17:11

Это моя точка зрения. Какой бы метод вы ни использовали, вы можете сгенерировать только ограниченное число возможных случайных чисел, и это зависит от используемого вами метода. Итак, вам придется конкретно выбрать один метод, и это определит вероятность получения верхней границы — если, опять же, это как-то актуально.

Thierry Lathuille 27.06.2024 17:17

@ThierryLathuille Наша задача — найти метод, который действительно выдает верхнюю границу x и делает это с той же вероятностью, что и любое другое число с плавающей запятой в [0,x]. Поскольку измерение радиоактивного распада обычно невозможно, статистическая/практическая однородность вполне подойдет. Что вы думаете о решении jakevdp?

AlMa1r 27.06.2024 17:22

@AlMa1r: Процедура генерации, которая присваивает равную вероятность каждому числу с плавающей запятой в диапазоне [0, x], будет чрезвычайно смещена в сторону малых значений, поскольку маленьких чисел с плавающей запятой гораздо больше, чем больших.

user2357112 10.07.2024 12:44

Попытка сделать это сталкивается с проблемами как со стороны «идеальных распределений действительных чисел», так и со стороны «реальности с плавающей запятой». Что касается «идеальных распределений действительных чисел», равномерное распределение в интервале действительных чисел [0, x] присваивает выходному значению x вероятность 0 и функционально идентично равномерному распределению в интервале [0, x). Аппроксимации этих распределений с плавающей запятой будут идентичными.

user2357112 10.07.2024 12:53

Что касается «реальности плавающей запятой», numpy.random.uniform на самом деле не обещает, что все числа с плавающей запятой в выходном диапазоне на самом деле будут возможными выходными данными. Для общих диапазонов выходных данных он не сможет выдавать все допустимые выходные данные. Это справедливо почти для каждой реализации аналогичной функциональности на разных языках и в библиотеках. Таким образом, даже с чем-то вроде ответа jakevdp нет никакой гарантии, что удастся получить на выходе нужное значение конечной точки.

user2357112 10.07.2024 12:59

@user2357112 user2357112 Хорошее замечание по поводу предвзятости к небольшим значениям. Это не то, чего мы действительно хотим. Мы хотим, чтобы равномерное распределение было аппроксимировано ближайшими значениями с плавающей запятой. В этом случае вероятность получения x не будет равна нулю, поскольку случайные числа, немного меньшие, чем x, будут аппроксимироваться к x. Я думаю о правильной математической формулировке; если он у вас есть, отредактируйте вопрос соответствующим образом.

AlMa1r 10.07.2024 15:05
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
10
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете настроить конечную точку на следующее число с плавающей запятой после максимального:

import numpy as np

def uniform_with_endpoint(low=0, hi=1, size=None):
  return np.random.uniform(low, np.nextafter(hi, np.inf), size=size)

Это дает равномерное распределение, в котором hi входит в возможные результаты.

Спасибо! Я не знал о numpy.nextafter.

AlMa1r 27.06.2024 17:27

Другие вопросы по теме