使用itertools.product时生成独立随机数的实现方案
如何让itertools.product结合生成器时生成独立随机数
我明白你的问题了——你的随机生成器目前只在第一次调用时产出一个随机数,之后就耗尽了,所以itertools.product会把这个单一值重复用在所有组合里。要解决这个问题,我们需要让随机生成器每次迭代都能产生新的随机数,而不是只生成一次。
解决方案代码
修改你的生成器函数,当启用随机模式时,用无限循环持续生成随机数:
import itertools import random import numpy as np def gen(useRandom, lowerBound, upperBound, stepSize=1): if useRandom: # 无限生成随机数,直到其他有限生成器遍历完毕 while True: yield random.uniform(lowerBound, upperBound) else: for steppedVal in np.arange(lowerBound, upperBound, stepSize): yield steppedVal
测试效果
双变量场景
运行以下代码:
print("双变量组合结果:") for vectors in itertools.product(gen(True,3,6), gen(False,10,30,5)): print(vectors)
你会得到类似这样的输出,每个组合的随机数都是独立的:
(4.1802347587349857, 10) (3.7128578913746897, 15) (5.8912734809721957, 20) (4.4163620543645585, 25)
多变量场景
针对你提到的十余个变量的复杂场景,这个方案同样适用。比如测试三个变量的情况:
print("\n多变量组合结果:") for vectors in itertools.product(gen(True,3,6), gen(False,10,30,5), gen(False,5,10)): print(vectors)
输出会保留所有非随机变量的笛卡尔组合,同时每个组合的随机数都是唯一的:
(4.231567890123456, 10, 5) (3.567890123456789, 10, 6) (5.123456789012345, 10, 7) (4.876543210987654, 10, 8) (3.987654321098765, 10, 9) (5.43210987654321, 15, 5) ...
原理说明
- 当
useRandom=True时,生成器通过while True无限产出随机数,这样itertools.product在遍历其他有限生成器的所有组合时,每次从随机生成器取元素都会得到一个新的随机值。 - 由于其他非随机生成器是有限的,
itertools.product会在遍历完所有可能的组合后自动停止,不会陷入无限循环。 - 这个方案完全在生成器层面处理,不需要事后修改数据集,不会额外增加计算开销,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

