Python:如何创建具有动态参数数量的参数网格
Python: how to create a parameter grid with dynamic number of parameters
假设为感兴趣的参数范围提供了一个字典,其中包含每个感兴趣的参数的范围:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
目标是提取此网格上的每个参数配置。上例中有4个这样的,对应2个a
的值,2个b
的值:
G1 = {'a': 1, 'b': 3, 'c': 1 }
G2 = {'a': 2, 'b': 3, 'c': 1 }
G3 = {'a': 1, 'b': 3, 'c': 2.5 }
G4 = {'a': 2, 'b': 3, 'c': 2.5 }
编写两个嵌套的 for 循环来生成所有此类配置很简单,当 G
.[=19 中的列表数量可变时,对于一般情况如何做到这一点就变得不那么简单了=]
我想到的唯一解决方案是创建一个与参数数量一样长的多索引向量 vec=[0,0]
,并递增以迭代所有可能的配置:[0,0] -> [1,0] -> [0,1] -> [1,1]
:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
def get_configs(G):
keys = list(G.keys())
lists = list(G.values())
sizes = [len(l) for l in lists]
num_confs = np.prod(sizes)
index = [0]*(len(G)+1)
configs = []
while len(configs)<num_confs:
configs.append( {keys[i]: lists[i][index[i]] for i in range(len(G))})
index[0] += 1
cur = 0
while len(configs)<num_confs and index[cur]>=sizes[cur]:
index[cur]=0
cur += 1
index[cur] += 1
return configs
configs = get_configs(G)
print(configs)
但是,解决方案似乎有点过于复杂和难看。是否有使用 python 的干净解决方案?
这是一个使用 itertools.product
的通用实现:
from itertools import product
def dict_configs(d):
for vcomb in product(*d.values()):
yield dict(zip(d.keys(), vcomb))
用法:
>>> G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
>>> for config in dict_configs(G):
... print(config)
...
{'a': 1, 'b': 3, 'c': 1}
{'a': 1, 'b': 3, 'c': 2.5}
{'a': 2, 'b': 3, 'c': 1}
{'a': 2, 'b': 3, 'c': 2.5}
假设为感兴趣的参数范围提供了一个字典,其中包含每个感兴趣的参数的范围:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
目标是提取此网格上的每个参数配置。上例中有4个这样的,对应2个a
的值,2个b
的值:
G1 = {'a': 1, 'b': 3, 'c': 1 }
G2 = {'a': 2, 'b': 3, 'c': 1 }
G3 = {'a': 1, 'b': 3, 'c': 2.5 }
G4 = {'a': 2, 'b': 3, 'c': 2.5 }
编写两个嵌套的 for 循环来生成所有此类配置很简单,当 G
.[=19 中的列表数量可变时,对于一般情况如何做到这一点就变得不那么简单了=]
我想到的唯一解决方案是创建一个与参数数量一样长的多索引向量 vec=[0,0]
,并递增以迭代所有可能的配置:[0,0] -> [1,0] -> [0,1] -> [1,1]
:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
def get_configs(G):
keys = list(G.keys())
lists = list(G.values())
sizes = [len(l) for l in lists]
num_confs = np.prod(sizes)
index = [0]*(len(G)+1)
configs = []
while len(configs)<num_confs:
configs.append( {keys[i]: lists[i][index[i]] for i in range(len(G))})
index[0] += 1
cur = 0
while len(configs)<num_confs and index[cur]>=sizes[cur]:
index[cur]=0
cur += 1
index[cur] += 1
return configs
configs = get_configs(G)
print(configs)
但是,解决方案似乎有点过于复杂和难看。是否有使用 python 的干净解决方案?
这是一个使用 itertools.product
的通用实现:
from itertools import product
def dict_configs(d):
for vcomb in product(*d.values()):
yield dict(zip(d.keys(), vcomb))
用法:
>>> G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
>>> for config in dict_configs(G):
... print(config)
...
{'a': 1, 'b': 3, 'c': 1}
{'a': 1, 'b': 3, 'c': 2.5}
{'a': 2, 'b': 3, 'c': 1}
{'a': 2, 'b': 3, 'c': 2.5}