2015-03-13 3 views
0

У меня есть этот тип строки:разделить значений в словаре в отдельных значениях

sheet = """ 
magenta 
turquoise,PF00575 
tan,PF00154,PF06745,PF08423,PF13481,PF14520 
turquoise, PF00011 
NULL 
""" 

Каждая строка начинается с идентификатором (например, загар, малиновый ...) То, что я хочу, чтобы подсчитать количество вхождений каждый номер PF для каждого идентификатора.

Итак, окончательная структура будет что-то вроде этого:

  magenta turquoise tan NULL 
PF00575 0   0  0 0 
PF00154 0   1  0 0 
PF06745 0   0  1 0 
PF08423 0   0  1 0 
PF13481 0   0  1 0 
PF14520 0   0  1 0 
PF00011 0   1  0 0 

Я начал с создания словаря аа, где каждое первое слово в строке является ключевым, а затем я хочу в качестве значений PF-номера за ним ,

Когда я использую этот код, я получаю значение как список строк, а не в виде отдельных значений в словаре:

lines = [] 
lines.append(sheet.split("\n")) 
flattened=[] 
flattened = [val for sublist in lines for val in sublist] 
pfams = [] 
for i in flattened: 
    pfams.append(i.split(",")) 
d = defaultdict(list) 
for i in pfams: 
pfam = i[0] 
d[pfam].append(i[1:]) 

Таким образом, результат:

defaultdict(<type 'list'>, {'': [[], []], 'magenta': [[]], 'NULL': [[]], 'turquoise': [['PF00575']], 'tan': [['PF00154', 'PF06745', 'PF08423', 'PF13481', 'PF14520']]}) 

Как могу ли я разделить PFnumbers так, чтобы они были отдельными значениями в словаре, а затем подсчитывали количество вхождений каждого уникального PF-номера на ключ?

+0

Start, показывая, что вы хотите, чтобы ваши 'final' данные выглядеть (предполагая, что все работает, как ожидалось) – sberry

+0

изменилось - спасибо – oaklander114

ответ

0

С благодарностью dwblas на devshed, это самый эффективный способ я нашел, чтобы решить задачу:

Я строю словарь, ключ является PFnumber, и список заказан, как я хочу цвета распечатаны.

colors_list= ['cyan','darkorange','greenyellow','yellow','magenta','blue','green','midnightblue','brown','darkred','lightcyan','lightgreen','darkgreen','royalblue','orange','purple','tan','grey60','darkturquoise','red','lightyellow','darkgrey','turquoise','salmon','black','pink','grey','null'] 
lines = sheet.splitlines() 
counts = {} 

for line in lines: 
    parts = line.split(",") 
    if len(parts) > 1: 
     ## doesn't break out the same item in the list many times 
     color=parts[0].strip().lower() 
     for key in parts[1:]: ## skip color 
      key=key.strip() 
      if key not in counts: 
       ## new key and list of zeroes-print it if you want to verify 
       counts[key]=[0 for ctr in range(len(colors_list))] 

      ## offset number/location of this color in list 
      el_number=colors_list.index(color) 
      if color > -1: ## color found 
       counts[key][el_number] += 1 
      else: 
       print "some error message" 

import csv 

with open("out.csv", "wb") as f: 
    writer=csv.writer(f) 
    writer.writerow(["PFAM",] + colors_list) 
    for pfam in counts: 
    writer.writerow([pfam] + counts[pfam]) 
1

Использование collections.Counter (https://docs.python.org/2/library/collections.html#collections.Counter)

import collections 

sheet = """ 
magenta 
turquoise,PF00575 
tan,PF00154,PF06745,PF08423,PF13481,PF14520 
NULL 
""" 

acc = {} 
for line in sheet.split('\n'): 
    if line == "NULL": 
     continue 
    parts = line.split(',') 
    acc[parts[0]] = collections.Counter(parts[1]) 

EDIT: Теперь накапливая все значения PF для каждого ключа

acc = collections.defaultdict(list) 
for line in sheet.split('\n'): 
    if line == "NULL": 
     continue 
    parts = line.split(',') 
    acc[parts[0]] += parts[1:] 
acc = {k: collections.Counter(v) for k,v in acc.iteritems()} 

Final редактировать Подсчитайте появление цветов на значение PF, который то, что мы были в конце концов, в конце:

acc = collections.defaultdict(list) 
for line in sheet.split('\n'): 
    if line == "NULL": 
     continue 
    parts = line.split(',') 
    for pfval in parts[1:] 
     acc[ pfval ] += [ parts[0] ] 
acc = {k: collections.Counter(v) for k,v in acc.iteritems()} 
+0

Thanks.I отрегулировать свой код к этому' акк = {} для линии в sheet.split ('\ n'): parts = line.split (',') если len (parts)> 1: acc [parts [0]] = collections.Counter (parts [1] .split (детали) ",")) ' Проблема в том, что он учитывает только последнее вхождение каждого ключа. Поэтому мне нужно сначала создать словарь, основываясь на каждой строке, потому что ключи встречаются более одного раза. Имеют смысл? Благодаря ! – oaklander114

+0

Это будет один из способов; если вы хотите агрегировать значения PF для всех вхождений одного и того же ключа, вы можете сначала агрегировать все значения PF на ключ, а затем, наконец, поместить их через счетчик. – haavee

+0

Я пытаюсь, но не работает. Не могли бы вы попробовать и изменить свой ответ? – oaklander114

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