Найдите совпадающие похожие ключевые слова в Python Dataframe - PullRequest
0 голосов
/ 01 августа 2020
joined_Gravity1.head()
Comments
____________________________________________________
0   Why the old Pike/Lyrik?
1   This is good
2   So clean
3   Looks like a Decoy
Input: type(joined_Gravity1)
Output: pandas.core.frame.DataFrame

Следующий код позволяет мне выбирать строки, содержащие ключевые слова: "ender"

joined_Gravity1[joined_Gravity1["Comments"].str.contains("ender", na=False)]

Вывод:

Comments
___________________________
194 We need a new Sender ?
7   What about the sender
179 what about the sender??

Как изменить код для включения слов, похожих на «Отправитель», таких как «snder», «bnder»?

Ответы [ 3 ]

1 голос
/ 01 августа 2020

Я не вижу причины, по которой regex=True внутри функции contains здесь не работает.

joined_Gravity1[joined_Gravity1["Comments"].str.contains(pat="ender|snder|bndr", na=False, regex=True)]

Я использовал только "ender|snder|bnder". Вы можете составить список всех таких слов, например, list_words, и передать pat='|'.join(list_words) в contains функцию выше.

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html

1 голос
/ 01 августа 2020

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

#!pip install fuzzywuzzy
from fuzzywuzzy import fuzz, process

word = 'sender'
others = ['bnder', 'snder', 'sender', 'hello']

process.extractBests(word, others)
[('sender', 100), ('snder', 91), ('bnder', 73), ('hello', 18)]

На основе этого вы можете решить, какой порог выбрать, а затем отметить те, которые выше порога, как совпадения (используя код, который вы использовали выше)

Вот способ сделать это в вашей точной постановке задачи с помощью функции -

df = pd.DataFrame(['hi there i am a sender', 
                   'I dont wanna be a bnder', 
                   'can i be the snder?', 
                   'i think i am a nerd'], columns=['text'])

#s = sentence, w = match word, t = match threshold
def get_match(s,w,t):
    ss = process.extractBests(w,s.split())
    return any([i[1]>t for i in ss])

#What its doing - Match each word in each row in df.text with 
#the word sender and see of any of the words have a match greater 
#than threshold ratio 70.
df['match'] = df['text'].apply(get_match, w='sender', t=70)
print(df)

                      text  match
0   hi there i am a sender   True
1  I dont wanna be a bnder   True
2      can i be the snder?   True
3      i think i am a nerd  False

Измените значение t с 70 на 80, если вы хотите более точное совпадение или меньше для более расслабленного матча.

Наконец, вы можете отфильтровать его -

df[df['match']==True][['text']]
                      text
0   hi there i am a sender
1  I dont wanna be a bnder
2      can i be the snder?
0 голосов
/ 01 августа 2020
from difflib import get_close_matches 

def closeMatches(patterns, word): 
     print(get_close_matches(word, patterns)) 

 list_patterns = joined_Gravity1[joined_Gravity1["Comments"].str.contains("ender", na=False)]

 word = 'Sender'
 patterns = list_patterns
 closeMatches(patterns, word) 
...