2016-01-08 2 views
2

У меня есть текст текста и 2 ключевых слова k1, k2. Я хочу найти все экземпляры, где k1 и k2 встречаются в непосредственной близости от 5 слов. Теперь я хочу, чтобы хранить 2 части информации из этой категории -[tricky] Поиск нескольких вхождений пар слов на основе близости. Python

  1. Числа таких матчей
  2. слова мудрого позиции лучшего матча. «Лучшее» здесь означает совпадение с максимальной близостью между k1 и k2. Это так, что я могу позже работать больше в этом матче.

У меня есть письменный код, но он не может найти матч, как показано ниже. Кроме того, это не дает мне количество совпадений или словосочетание.

import re 
text = 'the flory of gthys inhibition in this proffession by in aquaporin protein-1 its inhibition by the state of the art in aquaporin 2' 
a = 'aquaporin protein-1' 
b = 'inhibition' 
diff=500 
l = re.split(';|,|-| ', text) 
l1 = re.split(';|,|-| ', a) 
l2 = re.split(';|,|-| ', b) 
counts=[m.start() for m in re.finditer(a, text)] 
counts1=[m.start() for m in re.finditer(b, text)] 
for cc in counts: 
    for c1 in counts1: 
     if abs(cc-c1) < diff: 
      diff = abs(cc-c1) 
      values = (cc, c1) 

if text.find(a) < text.find(b): 
    r= (l.index(l2[0]) - l.index(l1[-1])) 
if text.find(a) > text.find(b): 
    r= (l.index(l1[0]) - l.index(l2[-1])) 
if r<5: 
    print 'matched' 
    print r 
+0

Почему вы удалили код, который вы размещены? Я предлагаю откинуть его назад. –

+0

@stribizhev Я думал, что это не очень хорошо. Однако я добавил его обратно. Благодаря! – Ciitk34

+2

Возможно, это не так, но это дает важную информацию, например, тот факт, что kw может быть фразами, плюс дает возможность aswerer хороший старт. – Akis

ответ

1

Так я получил свой собственный код для этого, ...

Дайте ему шанс. benefir, что она дает вам список кортежей (расстояния между словами, индекс ключевого слова 1, индекс keword 2):

text = 'the flory of gthys inhibition in this proffession by in aquaporin protein-1 its inhibition b , aquaporin protein-1' 
a = 'aquaporin protein-1' 
b = 'inhibition' 
k1 = "_KEYWORD_1_" 
k2 = "_KEYWORD_2_" 
text = text.replace(a, k1) 
text = text.replace(b, k2) 
l = text.split() 

d_idx = {k1:[], k2:[]} 
for k,v in enumerate(l): 
    if v == k1: 
     d_idx[k1].append(k) 
    elif v == k2: 
     d_idx[k2].append(k) 

distance = 5 
data = [] 
for idx1 in d_idx[k1]: 
    for idx2 in d_idx[k2]: 
     d = abs(idx1 - idx2) 
     if d<=distance: 
      data.append((d,idx1,idx2)) 

Давайте сортировать данные с расстояния ключевых слов:

data.sort(key=lambda x: x[0]) 

Так, ближайшее расстояние будет первый элемент данных (не может быть больше, чем один с тем же расстоянием, хотя):

print "Least distance: ", data[0][0] 
print "Index of kw1 and kw2: ", data[0][1:] 
print "Number of occurences: ", len(data) 

-------------- РЕДАКТИРОВАТЬ -----------
Итак, если вы хотите рассмотреть несколько слов как одно слово (для учета расстояния), вам придется сначала их заменить, этот (непроверенный) код может работать.

input = 'the flory of gthys inhibition in this proffession by in aquaporin protein-1 its inhibition b , aquaporin protein-1' 

a = 'aquaporin protein-1' 
b = 'inhibition' 

multiwords = ['aquaporin protein-1'] 
for mw in multiwords: 
    mw_no_space = mw.replace(' ', '__') 
    text = input.replace(mw, mw_no_space) 
k1 = a.replace(' ', '__') 
k2 = b.replace(' ', '__') 

l = text.split() 

d_idx = {k1:[], k2:[]} 
for k,v in enumerate(l): 
    if v == k1: 
     d_idx[k1].append(k) 
    elif v == k2: 
     d_idx[k2].append(k) 

distance = 10 
data = [] 
for idx1 in d_idx[k1]: 
    for idx2 in d_idx[k2]: 
     d = abs(idx1 - idx2) 
     if d<=distance: 
      data.append((d,idx1,idx2)) 

data.sort(key=lambda x: x[0]) 
print data 

print "Least distance: ", data[0][0] 
print "Index of kw1 and kw2: ", data[0][1:] 
print "Number of occurences: ", len(data) 
+0

принял это за дополнительные усилия! – Ciitk34

+0

эй, вы можете объяснить эту строку 'd_idx = {k1: [], k2: []}' – Ciitk34

+0

Я строю словарь с ключами 'k1' и' k2' (которые были бы вашими определенными целями) и назначая пустой список для каждого ключа (чтобы я мог добавлять данные позже). – tglaria

2

я решил заменить мульти-слово-ключевое слово в исходном тексте, так как могут быть обнаружены, так как они не распадаются после разделения строки в непечатаемых Таким образом фраз.

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

text = 'the flory of gthys inhibition in this proffession by in aquaporin protein-1 its inhibition b' 
a = 'aquaporin protein-1' 
b = 'inhibition' 
text = text.replace(a, 'k1') 
text = text.replace(b, 'k2') 
l = text.split() 
#print l 
#print 'k1 -> %s' % a 
#print 'k2 -> %s' % b 

last_a = -1 
last_b = -1 
counts = 0 
max_match_tuple = (6,0) # Initialize it like this since you want to track proximity less than 5 
for k,v in enumerate(l): 
     #print str(k) + '--->' + str(v) 
     if v == 'k1': 
       last_a = k 
       if k - last_b < 6 and last_b != -1: 
         counts = counts + 1 
         if k - last_b < max_match_tuple[0] - max_match_tuple[1]: 
          max_match_tuple = (k, last_b) 
     if v == 'k2': 
       last_b = k 
       if k - last_a < 6 and last_a != -1: 
         counts = counts + 1 
         if k - last_a < max_match_tuple[0] - max_match_tuple[1]: 
          max_match_tuple = (k, last_a) # Careful with the order here since it matters for above substruction 
print counts 
print max_match_tuple 

Немного объяснения с примерами о replace части. Вы заменяете в своем тексте фразу, которую вы хотите обнаружить с чем-то уникальным, на который не будет влиять раскол, чтобы иметь возможность использовать его в своем состоянии позже в вашем цикле. Поэтому, если вы хотите изменить ключевые слова, все, что вам нужно сделать, - это изменить определение переменных и b.

text = 'the flory of gthys inhibition in this proffession by in aquaporin  protein-1 its inhibition by the state of the art in aquaporin 2' 

a = 'aquaporin protein-1' 
text = text.replace(a, '******') 

print text 

# Output ---> the flory of gthys inhibition in this proffession by in ****** its inhibition by the state of the art in aquaporin 2 

b = 'in' 
text = text.replace(b, '+++') 

# Output ---> the flory of gthys +++hibition +++ this proffession by +++ ****** its +++hibition by the state of the art +++ aquapor+++ 2 
+0

Akis, большинство моих ключевых слов на самом деле многословное. Следовательно, этот код может не работать У вас есть идеи с такими ключевыми фразами? – Ciitk34

+0

В вашем примере вы хотите лечить 'aquaporin protein-1' как два слова' aquaporin' и 'protein-1'? – Akis

+0

no' aquaporin protein-1' является одним из ключевое слово и 'торможение' - это другое – Ciitk34

1

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

Simples форма: https://regex101.com/r/zW1dD3/2

(?P<K1>key1)\s+(?P<BETWEEN>(\w+\s+(?!key2)){0,4}\w+\s+)?(?P<K2>key2)

Образец данных:

word0 key1 key2 word1 word0 key1 word1 word2 key2 word3 word0 key1 word1 word2 word3 key2 word4 word0 key1 word1 word2 word3 word4 key2 word5 word0 key1 word1 word2 word3 word4 word5 key2 word6 word0 key1 word1 word2 word3 word4 word5 word6 key2 word7

+1

спасибо за ссылку – Ciitk34

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