Соответствие неполной строки в словаре Python - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть этот словарь, в котором ключи являются строковыми, а значения целочисленными, например:

{
...
'X ontology entity': 0, 
'X entity': 1, 
'image quality': 10, 
'right lower kidney': 10, 
'magnetic resonance imaging': 10312, 
'MR imaging': 10312, 
 ...
}

Я перебираю ключи этого словаря, пытаясь сопоставить серию токенов с этими ключами,Предположим, у меня есть следующие серии токенов:

MR imaging shows that the patient suffers from infection in right lower kidney.

Я просто разделил текст выше, используя пробелы.

Я хочу сопоставить МР-изображения, а также правую нижнюю почку, поскольку они средиключи в словаре.Итак, я написал следующий код, с которым я мог бы просто сопоставить «МРТ», а не «правую нижнюю почку».(Обратите внимание, что нижний правый угол отсутствует в наборе ключей)

found = []
for i, t in enumerate(tokens):
    term = [tokens[i]]
    j = deepcopy(i)
    while (' '.join(term) in self.db_terms):
        if j < len(tokens):
            j += 1
            term.append(tokens[j])
    found.append(' '.join(term[:-1]))
return set(found)

Я понятия не имею, как я могу найти «правый нижний» с помощью клавиш, сопоставить «правую нижнюю почку» и затем перейти к проверкетретий индекс.

Любая помощь будет оценена!Спасибо!

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Вы можете сделать это по-другому - начните с ключей и посмотрите, есть ли ключ в предложении.Это конечно проще.Будет ли это эффективно (или достаточно эффективно), зависит от того, насколько велики ваши входные данные.

d = {
    'X ontology entity': 0, 
    'X entity': 1, 
    'image quality': 10, 
    'right lower kidney': 10, 
    'magnetic resonance imaging': 10312, 
    'MR imaging': 10312, 
}

sentence = "MR imaging shows that the patient suffers from infection in right lower kidney."

[key for key in d.keys() if key in sentence]
# ['right lower kidney', 'MR imaging']
0 голосов
/ 30 ноября 2018

Просто переберите элементы и создайте новый dict, это можно сделать, используя понимание.

sentence = "MR imaging shows that the patient suffers from infection in right lower kidney."
tokens = {
    ...
    'X ontology entity': 0, 
    'X entity': 1, 
    'image quality': 10, 
    'right lower kidney': 10, 
    'magnetic resonance imaging': 10312, 
    'MR imaging': 10312, 
     ...
}

#Just in case, force lowercase
sencence = sentence.lower()

filtered = {token: value for token, value in tokens.items() if token.lower() in _sentence}
print(filtered)
#{'MR imaging', 'right lower kidney'}

Затем вы можете поместить их в предложение следующим образом:

for token, value in filtered.items():
    idx = _sentence.index(token.lower())
    sentence = "{} ({}){}".format(sentence[:idx+len(token)], value, sentence[idx+len(token):])
print(sentence)
#MR imaging (10312) shows that the patient suffers from infection in right lower kidney (10).
0 голосов
/ 30 ноября 2018

Похоже, вы имеете дело с Ngrams.Обратите внимание, что в этом ответе предполагается, что в вашем словаре много ключей, а не N-грамм.В этом случае более эффективно генерировать n-граммы из текста, а не перебирать ключи словаря (как в случае с другим ответом).

Начните с определения словаря keys.

keys = {
'X ontology entity': 0, 
'X entity': 1, 
'image quality': 10, 
'right lower kidney': 10, 
'magnetic resonance imaging': 10312, 
'MR imaging': 10312, 
}

Вам потребуется сгенерировать все N-граммы в пределах диапазона (который вы решите), и дляДля каждого n-грамма определите, существует ли он как ключ в вашем словаре.

import re

def get_ngrams(tokens, ngram_range):
    return {' '.join(tokens[i:i+r]) 
        for i in range(len(tokens)) for r in range(*ngram_range)}

ngram_range = (1, 4) # Right exclusive.
tokens = re.sub(r'[^a-zA-Z]', ' ', text).split()
found_tokens = set(filter(keys.__contains__, get_ngrams(tokens, ngram_range)))

print(found_tokens)
# {'MR imaging', 'right lower kidney'}

Имейте в виду, что для больших диапазонов и строк это становится дорогостоящей операцией.


Вы можете немного оптимизировать, признав, что не все N-граммы должны храниться в памяти перед фильтрацией.Мы можем сэкономить большое время, используя генератор и цикл:

def ngrams_generator(tokens, ngram_range):
    yield from (' '.join(tokens[i:i+r]) 
        for i in range(len(tokens)) for r in range(*ngram_range))

found_ngrams = set()
for ngram in ngrams_generator(tokens, ngram_range):
    if ngram in keys:
        found_ngrams.add(ngram)

print(found_ngrams)
# {'MR imaging', 'right lower kidney'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...