2017-02-03 3 views
0

У меня есть следующий код, который проверяет, входят ли предложения в фрейм данных в список. Если это так, часть должна быть заменена на ''.Замена подобных предложений в data.frame

import pandas as pd 
input_set = pd.DataFrame([['Thanks for the mail Harry', 1], ['Thanks for mailing Harry', 1]], columns=('Sentence', 'ticketID')) 


def reduceString(string, listSentences): 
for i in listSentences: 
    new_string = string.replace(i, '') 
    return(new_string) 

listSentences = ['Thanks for the '] 

for index, sentence in input_set.iterrows(): 
string = reduceString(sentence['Sentence'], listSentences) 
print(string) 

Все работает.

Однако, я хотел бы сделать его немного более надежным с включением модуля diff. Цель заключается в том, что не только точные предложения удаляются, но и предложения, которые похожи на x%.

Поэтому я попытался корректировки кода с этим:

import difflib 
def reduceString2(string, listSentences): 
for i in listSentences: 
    ratio = difflib.SequenceMatcher(None, i, string).ratio() 
    print(ratio) 
    if(ratio > 0.6): 
    new_string = string.replace(i, '') 
    return(new_string) 

Однако, если я пытаюсь сейчас работает:

for index, sentence in input_set.iterrows(): 
    string = reduceString2(df['Sentence'], listSentences) 

Это не меняет второе предложение, пока действительно ударил барьер if-statement. Может ли кто-нибудь сказать, почему соответствующий текст не заменен?

ответ

1

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

Во-вторых, даже если string и i похожи, вы пытаетесь заменить подстроку, которая необязательно существует в string. Вы можете использовать некоторые из методов, в SequenceMatcher найти правильные места, чтобы удалить:

import difflib 
def reduceString2(string, listSentences): 
for i in listSentences: 
    matcher = difflib.SequenceMatcher(None, i, string) 
    ratio = matcher.ratio() 
    print(ratio) 
    if(ratio > 0.6): 
    blocks = matcher.get_matching_blocks() 
    b_first, b_last = blocks[0], blocks[-2] 
    new_string = string[:b_first[1]] + string[b_last[1] + b_last[2]:] 
    return(new_string) 

Однако этот подход, в частности, даст вам:

mail Harry 
Harry 

Поскольку последний пробел в 'Thanks for the ' сочетается с пробелы перед Harry во втором предложении. Другим вариантом было бы, чтобы удалить только замененные блоки, но это даст вам:

mail Harry 
mailingHarry 

Что, вероятно, не то, что можно было бы ожидать. Поэтому вам нужно решить, что делать с этими подобранными блоками.

Кроме того, вы можете рассмотреть возможность использования quick_ratio() или real_quick_ratio() в качестве быстрого фильтра (см SequenceMatcher documentation), а также других мелких вещей, как зачистки и lowercasing строки.