Получение верхнего значения в словаре с несколькими значениями под одним ключом - PullRequest
1 голос
/ 16 февраля 2012

Я немного новичок в Python, и у меня есть проблема.У меня есть файл с 5 результатами для каждого уникального идентификатора.Каждый результат имеет процентное совпадение и различные другие данные.Моя цель - найти результат с наибольшим процентным соответствием, а затем получить дополнительную информацию из этой исходной строки.Например,

Name    Organism    Percent Match     Misc info
1        Human        100              xxx     
1        Goat          95              yyy
1        Pig           90              zzz   

Я пытаюсь решить эту проблему, помещая каждый ключ в словарь со значениями, каждый процент которых соответствует уникальному для данного имени (то есть несколько значений для каждого ключа).Единственный способ, которым я могу думать, - это преобразовать значения в этом словаре в список, а затем отсортировать список.Затем я хочу получить наибольшее значение в списке (список [0] или список [-1]), а затем получить дополнительную информацию из исходной строки.Вот мой код до сих пор

list = []  
if "1" in line: 
    id = line
    bsp = id.split("\t")
    uid = bsp[0]
    per = bsp[2]

    if not dict.has_key(uid):
        dict[uid] = []
    dict[uid].append(per)
    list = dict[uid]
    list.sort()
if list[0] in dict:
    print key

В итоге мы просто печатаем каждую клавишу, а не только ту, которая имеет наибольший процент.Какие-нибудь мысли?Спасибо!

Ответы [ 4 ]

2 голосов
/ 16 февраля 2012

Вы можете использовать csv для анализа файла данных, выделенного табуляцией, (хотя опубликованные вами данные выглядят как данные, разделенные столбцами!?)

Поскольку первая строка в вашем файле данных содержит имена полей, DictReader удобен, так что вы можете ссылаться на столбцы с помощью удобочитаемых имен.

csv.DictReader возвращает итерацию строк (диктов). Если вы берете max итерируемого с использованием столбца Percent Match в качестве key, вы можете найти строку с самым высоким процентным соответствием:

Использование этих данных (с разделителями табуляции) как test.dat:

Name    Organism    Percent Match   Misc    info
1   Human   100 xxx
1   Goat    95  yyy
1   Pig 90  zzz
2   Mouse   95  yyy
2   Moose   90  zzz
2   Manatee 100 xxx

программа

import csv

maxrows = {}
with open('test.dat', 'rb') as f:
    for row in csv.DictReader(f, delimiter = '\t'):
        name = row['Name']
        percent = int(row['Percent Match'])
        if int(maxrows.get(name,row)['Percent Match']) <= percent:
            maxrows[name] = row

print(maxrows)

выходы

{'1': {'info': None, 'Percent Match': '100', 'Misc': 'xxx', 'Organism': 'Human', 'Name': '1'}, '2': {'info': None, 'Percent Match': '100', 'Misc': 'xxx', 'Organism': 'Manatee', 'Name': '2'}}
1 голос
/ 16 февраля 2012

Я думаю, вы можете искать что-то вроде:

from collections import defaultdict

results = defaultdict(list)
with open('data.txt') as f:
    #next(f)      # you may need this so skip the header
    for line in f:
        splitted = line.split()
        results[splitted[0]].append(splitted[1:])

maxs = {}
for uid,data in results.items():
    maxs[uid] =  max(data, key=lambda k: int(k[1]))

У меня есть свидетельство о файле вроде:

Name    Organism    Percent Match     Misc info
1        Human        100              xxx     
1        Goat          95              yyy
1        Pig           90              zzz   
2        Pig           85              zzz   
2        Goat          70              yyy

И результат был:

{'1': ['Human', '100', 'xxx'], '2': ['Pig', '85', 'zzz']}
1 голос
/ 16 февраля 2012

Вы должны быть в состоянии сделать что-то вроде этого:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))

После прочтения файла lines будет выглядеть примерно так:

>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]

И затем вы хотите получитьзапись от lines, где значение int третьего элемента является наибольшим, что можно выразить так:

>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']

Так что в конце этого best_match будет список сданные из интересующей вас строки.

Или, если вы хотите получить действительно сложную информацию, вы можете получить строку за один (сложный) шаг:

with open('data.txt') as file:
    best_match = max((s.split() for s in file if s.startswith('1')),
                     key=lambda k: int(k[2]))
0 голосов
/ 16 февраля 2012
with open('datafile.txt', 'r') as f:
    lines = file.read().split('\n')

matchDict = {}

for line in lines:
    if line[0] == '1':
        uid, organism, percent, misc = line.split('\t')
        matchDict[int(percent)] = (organism, uid, misc)

highestMatch = max(matchDict.keys())

print('{0} is the highest match at {1} percent'.format(matchDict[highestMatch][0], highestMatch))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...