2014-11-12 2 views
0

У меня есть словарь, который выглядит следующим образом:средства вычисления значений для подгрупп ключей в питона словаре

cq={'A1_B2M_01':2.04, 'A2_B2M_01':2.58, 'A3_B2M_01':2.80, 'B1_B2M_02':5.00, 
'B2_B2M_02':4.30, 'B2_B2M_02':2.40 etc.} 

Мне нужно вычислить среднее триплетов, где ключи [2:] согласны. Таким образом, я бы в идеале хотел бы получить еще один словарь, который будет:

new={'_B2M_01': 2.47, '_B2M_02': 3.9} 

Данные/должны быть в тройни так что в теории я мог бы просто получить средства последовательных значений, но в первую очередь, у меня есть это в словаре, поэтому ключи/значения, скорее всего, будут переупорядочены, кроме того, я предпочел бы придерживаться имен, как проверку качества для триплетов, назначенных именам (позже я добавлю немного сообщение об ошибке, когда будет больше, чем три на группу). Я пробовал создать словарь, в котором ключи были бы _B2M_01 и _B2M_02, а затем прокручивали исходный словарь, чтобы сначала добавить все значения, назначенные этим группам ключей, чтобы я мог позже вычислить среднее значение, но я получаю ошибки даже на первом этапе и в любом случае, я не уверен, что это наиболее эффективный способ сделать это ...

cq={'A1_B2M_01':2.4, 'A2_B2M_01':5, 'A3_B2M_01':4, 'B1_B2M_02':3, 'B2_B2M_02':7, 'B3_B2M_02':6} 
trips=set([x[2:] for x in cq.keys()]) 
new={} 
for each in trips: 
    for k,v in cq.iteritems(): 
     if k[2:]==each: 
      new[each].append(v) 

Traceback (most recent call last): 
File "<pyshell#28>", line 4, in <module> 
    new[each].append(v) 
KeyError: '_B2M_01' 

Я был бы очень признателен за любые предложения. Кажется, это довольно простая операция, но я застрял.

Альтернативный результат, который был бы еще лучше, заключался бы в том, чтобы получить словарь, который содержит все имена, используемые как в cq, но со значениями, являющимися средствами группы. Таким образом, конечным результатом будет:

final={'A1_B2M_01':2.47, 'A2_B2M_01':2.47, 'A3_B2M_01':2.47, 'B1_B2M_02':3.9, 
'B2_B2M_02':3.9, 'B2_B2M_02':3.9} 

ответ

0
cq={'A1_B2M_01':2.4, 'A2_B2M_01':5, 'A3_B2M_01':4, 'B1_B2M_02':3, 'B2_B2M_02':7, 'B3_B2M_02':6} 

sums = dict() 
for k, v in cq.iteritems(): 
    _, p2 = k.split('_', 1) 
    if p2 not in sums: 
     sums[p2] = [0, 0] 
    sums[p2][0] += v 
    sums[p2][1] += 1 


res = {} 
for k, v in sums.iteritems(): 
    res[k] = v[0]/float(v[1]) 

print res 

также может быть сделано с одной итерации

+0

Эта работа тоже, очень приятно, спасибо! – branwen85

2

Нечто подобное должно работать. Возможно, вы можете сделать его немного более элегантным.

cq = {'A1_B2M_01':2.04, 'A2_B2M_01':2.58, 'A3_B2M_01':2.80, 'B1_B2M_02':5.00, 'B2_B2M_02':4.30, 'B2_B2M_02':2.40 } 
sum = {} 
count = {} 
mean = {} 
for k in cq: 
    if k[2:] in sum: 
     sum[k[2:]] += cq[k] 
     count[k[2:]] += 1 
    else: 
     sum[k[2:]] = cq[k] 
     count[k[2:]] = 1 
for k in sum: 
    mean[k] = sum[k]/count[k] 
+0

Это работает и собирается вместе, что я пытался пишите, спасибо! – branwen85

+0

, если значения являются целыми числами, тогда среднее значение даст вам целое число. бросить плавать, чтобы быть уверенным – gosom

0

Группировка:

SEPARATOR = '_' 
cq={'A1_B2M_01':2.4, 'A2_B2M_01':5, 'A3_B2M_01':4, 'B1_B2M_02':3, 'B2_B2M_02':7, 'B3_B2M_02':6} 

groups = {} 
for key in cq: 
    group_key = SEPARATOR.join(key.split(SEPARATOR)[1:]) 
    if group_key in groups: 
     groups[group_key].append(cq[key]) 
    else: 
     groups[group_key] = [cq[key]] 

Генерация средств:

def means(groups): 
    for group, group_vals in groups.iteritems(): 
     yield (group, float(sum(group_vals))/len(group_vals),) 

print list(means(groups)) 
+0

К сожалению, это не сработает. Я не могу сделать split'_ ', поскольку группы характеризуются B2M_0x, поэтому, если бы я разделил его, я получил бы еще много и не корректных групп. Не знаю, почему, но я также получил Type Error, пытающийся запустить ваше решение (если group_key в группах: TypeError: unhashable type: 'list') – branwen85

+0

@ branwen85 Я отредактировал решение. Я не понял ваш комментарий, это группы, определяемые строкой до первого подчеркивания? –

+1

Извините, это не очень легко объяснить! Нет, группы определяются последними 2 частями. Таким образом, группы B2M_01 и B2M_02. – branwen85

Смежные вопросы