Как создать L-список из n ненулевых случайных десятичных знаков, где каждый список суммируется до 1.0?

Ищете быстрый способ создания L количества списков из n суммы десятичных знаков, сумма которых равна 1. Каждое число должно быть> = 0,01

Желаемый результат:

где L = 200, n = 6

[0.20, 0.22, 0.10, 0.06, 0.04, 0.38] [0.32, 0.23, 0.18, 0.07, 0.05, 0.15] ... # There are 200 of these 

где L = 200, n = 3

 [0.90, 0.10, 0.10] [0.35, 0.25, 0.30] ... # There are also 200 of these 

Трудная часть, о которой я не могу думать о практическом решении, заключается в том, что в каждом списке нет нулей. Это становится особенно тяжелым, когда n достигает больших чисел. Как вы распределяете фрагменты значения 1 соответственно?

4 Solutions collect form web for “Как создать L-список из n ненулевых случайных десятичных знаков, где каждый список суммируется до 1.0?”

Это должно быть очень быстро, поскольку оно использует numpy.

Он будет автоматически повторять рандомизацию, если она получает 0.0, но это маловероятно. Цикл while был записан до того, как OP скорректировало ненулевое требование, чтобы оно было выше 0,01. Чтобы исправить это, вы можете изменить блок while, чтобы включить весь последующий код, и рассчитать количество нарушений любого желаемого ограничения в конце способом, аналогичным тому, что показано для обнаружения нулей. Но это может стать медленным, когда L велико по сравнению с вероятностью нарушения ограничения. В некотором смысле легче всего выполнить первоначальное требование >0.0 .

После цикла while каждый элемент матрицы L xn равномерно распределяется по (0.0,1.0) без каких-либо 0 или 1 сек. Каждая строка суммируется и используется для формирования матрицы шкалы, то есть матрица, умноженная на случайную матрицу, для получения строк, которые автоматически суммируются до 1,0

  import numpy as np def random_proportions(L,n): zeros = 1 while zeros>0: x = np.random.random(size=(L,n)) zeros = np.sum(x==0.0) sums = x.sum(axis=1) scale = np.diag(1.0/sums) return np.dot(scale, x) 

EDIT: вышеописанная матрица LxL для масштаба, которая неэффективна для памяти. Это будет OOM до L = 10 ** 6. Мы можем исправить это, используя процедуру нормализации вещания, предложенную в этом ответе

 import numpy as np def random_proportions(L,n): zeros = 1 while zeros>0: x = np.random.random(size=(L,n)) zeros = np.sum(x==0.0) sums = x.sum(axis=1).reshape(L,1) # reshape for "broadcasting" effect return x/sums 

Эта вторая версия рассчитает 1 миллионный список размером 10 примерно на 1/3 секунды на AMD FX-8150 с 16 ГБ оперативной памяти:

 %timeit l = random_proportions(1000000,10) 1 loops, best of 3: 347 ms per loop 

Вот как вы получаете n чисел, которые составляют до одного: выберите n случайных чисел в произвольном диапазоне по вашему выбору (например, от 1 до 10), а затем разделите их на сумму.

Это должно сделать трюк:

 import random def floatPartition(n, total): answer = [] for _ in range(n-1): num = random.uniform(0, total) answer.append(num) total -= num answer.append(total) return answer def paritions(n,L): return [floatPartition(n, 1) for _ in range(L)] if __name__ == "__main__": answer = paritions(6,200) 

Я не проверял других на скорость, но это algorthim производит 1 000 000 списков длины 10 с элементами 0,01-0,99 с шагом 0,01 за 20 секунд:

 import random def rand_list(n): sub_list = [] max_val = 100 - n + 1 # max needs to be n-1 less than 100 for repetition in xrange(n-1): sub_list += [random.randrange(1, max_val)] max_val -= (sub_list[-1] - 1) # decrease the range by the latest element added - 1 sub_list += [max_val] # use the remainder for the last value, this way it adds to 100 return [round(x/100.0, 2) for x in sub_list] # convert to 0.01 - 0.99 with list comprehension 
  • Заполнение вкладки ipython для пользовательского класса dict
  • Python: «TypeError: __str__ возвращен не-строка», но все же печатает на выходе?
  • Создание словаря с помощью клавиш и измененных объектов. Сюрприз
  • Установка модуля Python 6
  • «С» в Python с несколькими файлами для обработки
  • Django Model Mixins: наследовать от моделей. Моделя или из объекта?
  • Как отобразить все слова, содержащие эти символы?
  • Оставшиеся значения пустые, если не переданы в str.format
  • Python - лучший язык программирования в мире.