2016-11-15 56 views
1

我正在制作一个python程序,其中随机值生成n次,用作模型仿真的参数值。python词典,赋值为总和值为一定值的随机值

我定义每个参数的边界的字典,例如:

parameters = {'A': random.uniform(1,10), 'B': random.uniform(20,40)} 

我想添加一些参数,其总和必须是1,是这样的:

params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['C1']} 

后者显然不起作用KeyError: 'C1'

我也试过类似的东西:

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40), 'C': {'C1': None,'C2': None}} 

def class_fractions(): 
    for key in params['C']: 
     if key == 'C1': 
      params['C'][key] = random.uniform(0.0,1.0) 
     if key == 'C2': 
      params['C'][key] = 1.0 - params['C'][key] 

但在调用函数后我得到的类型错误

TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'

什么建议吗?

+0

您的for循环将不起作用,因为字典不保证顺序。所以C2可以在C1之前执行。 – Marcin

+0

'params ['C'] ['C2']'总是'None'。从未分配过一个值。 – helloV

回答

1

从您使用for循环看起来,您可能确实拥有的参数不止两个。在这种情况下,您可以生成一个填充了随机数的值列表,然后然后将其缩小为一,as described in this other answer。然后迭代字典键和列表项目的压缩视图,并将项目分配给字典。

或者,直接在字典操作:

params = {k: random.uniform(0, 1) for k in ('C1', 'C2', 'C3')} 
total = sum(params.values()) 
params = {k: (v/total) for k, v in params.items()} 
2

您的代码问题是因为dict未在Python中进行排序。当你这样做:

for key in params['C'] 

你比以前C1越来越C2关键。其实你甚至不需要迭代中,如字典的dict只需设置值:

def class_fractions(): 
    params['C']['C1'] = random.uniform(0.0,1.0) 
    params['C']['C2'] = 1.0 - params['C']['C1'] 

哟甚至不需要单独的功能,因为它仅更新同一字典,只要你不喜欢它:

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40)} # create partial dict 
c_dict = {'C1': random.uniform(1,10)} # create sub-dict to store random value 
c_dict['C2'] = 1 - c_dict['C1'] # get value that you want 
params['C'] = c_dict  # add entry into parent dict 
1

如果你真的想OT使用class_fraction,并在一次初始化参数,可以那么就需要使用OrderDict:

import random 
from collections import OrderedDict 

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40), 'C':OrderedDict([('C1', None),('C2', None)])} 


def class_fractions(): 
    for key in params['C']: 
     if key == 'C1': 
      params['C'][key] = random.uniform(0.0,1.0) 
     if key == 'C2': 
      params['C'][key] = 1.0 - params['C']['C1'] 


class_fractions() 
print(params) 

结果:

{'B': 37.3088618142464, 'A': 2.274415152225316, 'C': OrderedDict([('C1', 0.12703200100786471), ('C2', 0.8729679989921353)])}