У меня есть набор данных, который выглядит так
name col1 col2 col13
company1 Banking Finance B&F
company2 Utilities Utilities NaN
company3 Transportation Pipeline Transportation Utilities
company4 Consulting Tech Insurance
так далее.........
Поэтому мне нужно сравнить каждый столбец друг с другом и обозначить те, которые совсем не похожи (или синонимы) друг на друга. Например, у компании 4 нет ничего подобного, я хочу отметить это. компания 3 выглядит несколько схожей, поэтому я хочу отметить, что как почти аналогичный (желтый флаг) и зеленый, которые соответствуют, являются зелеными.
The output somewhat needs to look like this :
name col1 col2 col13 flag
company1 Banking Finance B&F green
company2 Utilities Utilities NaN green
company3 Transportation Pipeline Transportation Utilities yellow
company4 Consulting Tech Insurance red
Я знаю, что это похоже на очень большой вопрос, но может ли кто-нибудь дать мне начало -like, как подойти к этому. Какие алгоритмы соответствия строк можно использовать здесь?
Спасибо
Для начала вы можете использовать ratio
или partial_ratio
из fuzzywuzzy, чтобы получить сходство строк между ячейками той же строки. Затем вы также можете сравнить, являются ли каждая ячейка той же строки синонимами друг друга, используя лексическую базу данных, такую как WordNet (nltk
). Оговорка состоит в том, что предлагаемые синонимы для каждого слова являются исчерпывающими и не могут быть всеобъемлющими - мы можем видеть это, когда мы используем WordNet, но Banking
, Finance
и B&F
отмечены красным. Однако эти два подхода могут быть полезны, чтобы помочь вам начать.
Сначала установите зависимости:
pip install nltk fuzzywuzzy
Загрузить WordNet:
python
>>> nltk.download('wordnet')
[nltk_data] Downloading package wordnet to
[nltk_data] C:\Users\user\AppData\Roaming\nltk_data...
[nltk_data] Unzipping corpora\wordnet.zip.
True
Выполнить скрипт:
import pandas as pd
from nltk.corpus import wordnet as wn
from fuzzywuzzy import fuzz
df = pd.DataFrame({
'name': ['company 1', 'company 2', 'company 3', 'company 4'],
'col1': ['Banking', 'Utilities', 'Transportation', 'Consulting'],
'col2': ['Finance', 'Utilities', 'Pipeline Transportation', 'Utilities'],
'col3': ['B&F', 'NaN', 'Utilities', 'Insurance'],
})
def get_synonyms(word):
synonym_list = []
for synset in wn.synsets(word):
for lemma in synset.lemmas():
if not lemma.name() in synonym_list:
synonym_list.append(lemma.name().replace('_',' '))
return synonym_list
def check_flag(row):
col1_data = row['col1']
col2_data = row['col2']
col3_data = row['col3']
green_flag_threshold = 80
# Get Fuzzy Ratio
fuzz_ratio_1 = fuzz.ratio(col1_data,col2_data)
fuzz_ratio_2 = fuzz.ratio(col2_data,col3_data)
fuzz_ratio_3 = fuzz.ratio(col3_data,col1_data)
if col1_data == col2_data or col2_data == col3_data or col3_data == col1_data or green_flag_threshold < (fuzz_ratio_1 or fuzz_ratio_2 or fuzz_ratio_3):
return 'green'
# Check synonyms using Wordnet (nltk)
col1_syn_list = get_synonyms(col1_data)
col2_syn_list = get_synonyms(col2_data)
col3_syn_list = get_synonyms(col3_data)
all_data = [col1_data, col2_data, col3_data]
for col_data in all_data:
for word in col_data.split():
if word in (col1_syn_list or col2_syn_list or col3_syn_list):
return 'yellow'
return 'red'
df['flag'] = df.apply(check_flag, axis=1)
print(df)
Результаты:
col1 col2 col3 name flag
0 Banking Finance B&F company 1 red
1 Utilities Utilities NaN company 2 green
2 Transportation Pipeline Transportation Utilities company 3 yellow
3 Consulting Utilities Insurance company 4 red
Process finished with exit code 0