使用itertools产品时生成随机数

时间:2018-05-30 17:07:43

标签: python random 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)

关键部分是第2和第3发电机的每个配对仍然存在。

1 个答案:

答案 0 :(得分:3)

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