Генерация случайных чисел при использовании продукта itertools - PullRequest
0 голосов
/ 30 мая 2018

Я использую функцию генератора для создания упорядоченных списков чисел вдоль бокового itertools.product, чтобы создать всевозможное сравнение указанных чисел:

def gen(lowerBound, upperBound, stepSize = 1):
    for steppedVal in np.arange(lowerBound, upperBound, stepSize):
        yield steppedVal

for vectors in it.product(gen(3,6), gen(10,30,5)):
    print(vectors)

, которое, как и ожидалось, создает такой набор данных, как этот:

(3, 10)
(3, 15)
(3, 20)
(3, 25)
(4, 10)
(4, 15)
(4, 20)
(4, 25)
(5, 10)
(5, 15)
(5, 20)
(5, 25)

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

def gen(useRandom, lowerBound, upperBound, stepSize = 1):
    if useRandom:
        randomVal = random.uniform(lowerBound, upperBound)
        yield randomVal
    else:
        for steppedVal in np.arange(lowerBound, upperBound, stepSize):
            yield steppedVal

for vectors in itertools.product(gen(True,3,6), gen(False,10,30,5)):
    print(vectors)

я получаю это, а это не то, что мне нужно:

(4.4163620543645585, 10)
(4.4163620543645585, 15)
(4.4163620543645585, 20)
(4.4163620543645585, 25)

Как я могу изменить этот код так, чтобы каждое случайное число в этом наборе данныхуникален без необходимости изменять набор данных после факта, поскольку это добавляет огромные накладные расходы на вычисления.(Фактический набор данных содержит дюжину или около того переменных с 10-20 шагами в каждой).

Правка, для пояснения приведен желаемый результат:

(4.1802347587349857, 10)
(3.7128578913746897, 15)
(5.8912734809721957, 20)
(4.4163620543645585, 25)

Правка 2, чтобы быть вдвоеясно, я не хочу использовать функцию zip, поскольку это также может быть возможным выводом:

for vectors in itertools.product(gen(True,3,6), gen(False,10,30,5), gen(False,5,10):
    print(vectors)

(Some Random Number, 10, 5)
(Some Random Number, 10, 6)
(Some Random Number, 10, 7)
(Some Random Number, 10, 8)
(Some Random Number, 10, 9)
(Some Random Number, 15, 5)
(Some Random Number, 15, 6)
(Some Random Number, 15, 7)
(Some Random Number, 15, 8)
(Some Random Number, 15, 9)
(Some Random Number, 20, 5)
(Some Random Number, 20, 6)
(Some Random Number, 20, 7)
(Some Random Number, 20, 8)
(Some Random Number, 20, 9)
(Some Random Number, 25, 5)
(Some Random Number, 25, 6)
(Some Random Number, 25, 7)
(Some Random Number, 25, 8)
(Some Random Number, 25, 9)

Ключевая часть, являющаяся каждой парой 2-го и 3-го генераторов, все еще существует.

1 Ответ

0 голосов
/ 30 мая 2018

Ваш генератор звонит random.uniform только один раз.Я думаю, что вы хотите:

def gen(useRandom, lowerBound, upperBound, stepSize = 1):
    for steppedVal in np.arange(lowerBound, upperBound, stepSize):
        if useRandom:
            randomVal = random.uniform(lowerBound, upperBound)
            yield randomVal
        else:
            yield steppedVal

Теперь ваш вывод становится:

(4.229914739995998, 10)
(4.229914739995998, 15)
(4.229914739995998, 20)
(4.229914739995998, 25)
(5.52362641577289, 10)
(5.52362641577289, 15)
(5.52362641577289, 20)
(5.52362641577289, 25)
(4.507985392309242, 10)
(4.507985392309242, 15)
(4.507985392309242, 20)
(4.507985392309242, 25)

, который показывает, что вы получаете три разных случайных значения, соответствующих трем разам, когда запускается первый экземпляр генератора.

Обратите внимание, что вы также можете посмотреть на random.randrange, который, по сути, возвращает случайное целое число из range(lowerBound, upperBound, stepSize).Если вы замените random.uniform(lowerBound, upperBound) на random.randrange(lowerBound, upperBound, stepSize) в функции генератора, вы получите вывод:

(5, 10)
(5, 15)
(5, 20)
(5, 25)
(3, 10)
(3, 15)
(3, 20)
(3, 25)
(3, 10)
(3, 15)
(3, 20)
(3, 25)

На этот раз генератор выбрал случайное число из набора [3,4,5] для каждогоитерация.Обратите внимание, что это не обязательно дает уникальные числа на каждой итерации!Вы можете использовать random.shuffle, если это то, что вы ищете.

...