使用itertools产品时生成随机数

我正在使用生成器函数沿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)

关键部分仍然是第二和第三发生器的每对.

解决方法:

您的生成器仅调用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.

上一篇:python-TypeError:’Figure’对象不可迭代(itertools)


下一篇:迭代器切片操作