Я попытался найти ответ в SO, но не нашел никакой помощи.
Вот что я пытаюсь сделать:
У меня есть фрейм данных (вот небольшой пример этого):
df = pd.DataFrame([[1, 5, 'AADDEEEEIILMNORRTU'], [2, 5, 'AACEEEEGMMNNTT'], [3, 5, 'AAACCCCEFHIILMNNOPRRRSSTTUUY'], [4, 5, 'DEEEGINOOPRRSTY'], [5, 5, 'AACCDEEHHIIKMNNNNTTW'], [6, 5, 'ACEEHHIKMMNSSTUV'], [7, 5, 'ACELMNOOPPRRTU'], [8, 5, 'BIT'], [9, 5, 'APR'], [10, 5, 'CDEEEGHILLLNOOST'], [11, 5, 'ACCMNO'], [12, 5, 'AIK'], [13, 5, 'CCHHLLOORSSSTTUZ'], [14, 5, 'ANNOSXY'], [15, 5, 'AABBCEEEEHIILMNNOPRRRSSTUUVY']],columns=['PartnerId','CountryId','Name'])
Моя цель - найти PartnerId
s, которые Name
похожи, по крайней мере, до определенного ratio
.
Кроме того, я хочу сравнить только PartnerId
с одинаковыми CountryId
. Соответствующие PartnerId
s должны быть добавлены в список и, наконец, записаны в новый столбец в кадре данных.
Вот моя попытка:
itemDict = {item[0]: {'CountryId': item[1], 'Name': item[2]} for item in df.values}
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
def calculate_similarity(x,itemDict):
own_name = x['Name']
country_id = x['CountryId']
matching_ids = []
for k, v in itemDict.items():
if k != x['PartnerId']:
if v['CountryId'] == country_id:
ratio = similar(own_name,v['Name'])
if ratio > 0.7:
matching_ids.append(k)
return matching_ids
df['Similar_IDs'] = df.apply(lambda x: calculate_similarity(x,itemDict),axis=1)
print(df)
Вывод:
PartnerId CountryId Name Similar_IDs
0 1 5 AADDEEEEIILMNORRTU []
1 2 5 AACEEEEGMMNNTT []
2 3 5 AAACCCCEFHIILMNNOPRRRSSTTUUY [15]
3 4 5 DEEEGINOOPRRSTY [10]
4 5 5 AACCDEEHHIIKMNNNNTTW []
5 6 5 ACEEHHIKMMNSSTUV []
6 7 5 ACELMNOOPPRRTU []
7 8 5 BIT []
8 9 5 APR []
9 10 5 CDEEEGHILLLNOOST [4]
10 11 5 ACCMNO []
11 12 5 AIK []
12 13 5 CCHHLLOORSSSTTUZ []
13 14 5 ANNOSXY []
14 15 5 AABBCEEEEHIILMNNOPRRRSSTUUVY [3]
Мои вопросы сейчас:
1.) Есть ли более эффективный способ его вычисления? У меня сейчас около 20 000 строк и еще много в ближайшем будущем.
2.) Можно ли "избавиться" от itemDict и сделать это прямо из фрейма данных?
3.) Может быть, лучше использовать другую меру расстояния?
Большое спасибо за помощь!