Python-код для извлечения похожих строк из 2 списков

У меня есть 2 списка имен игроков из 2 разных источников.

names1 = ['CJ McCollum', 'Metta World', 'LeBron James', 'Stephen Curry']

names2 = ['Metta World Peace', 'Steph Curry', 'Kevin Durant', 'CJ McCollum']

Проблема здесь в том, что, хотя они и являются одними и теми же игроками, есть некоторые различия в том, как их имена упоминаются в двух источниках. Я использовал следующий код для поиска похожих имен (все символы в names1 должны существовать в names2 ):

idx = np.zeros(3)
i = 0
for x, y in enumerate(names1):
    for z, w in enumerate(names2):
        if y in w:
            idx[i] = x
            i = i+1

Для каждой итерации names1 код names1 все итерации names2 и выводит индекс записи, аналогичный записи в names2 . idx - это список, который должен содержать индекс похожих строк. i индекс индекса. Каждый раз, когда обнаруживается похожая строка, она сохраняется в idx и i увеличивается на 1, так что следующая найденная запись будет записана в индекс i+1 idx .

Ожидаемый ответ: idx = [0, 1, 3]

Однако я получаю следующую ошибку: list assignment index out of range

Как я могу исправить код и есть ли лучший способ решить эту проблему?

Всего 2 ответа


Вот попытка (здесь я посчитал, что только такие изменения, как MC = MC, использование majuscule и minuscule и расстояние Левенштейна, меньшее 2, принято считать двумя именами одинаковыми):

import numpy as np


def levenshtein_distance(v, w):
    n, m = len(v), len(w)
    M = np.zeros((n+1, m+1))
    for i in range(n+1):
        M[i, 0] = i
    for j in range(m+1):
        M[0, j] = j
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if v[i-1] == w[j-1]:
                M[i, j] = min(M[i-1, j] + 1, M[i, j-1] + 1, M[i-1, j-1])
            else:
                M[i, j] = min(M[i-1, j] + 1, M[i, j-1] + 1, M[i-1, j-1] + 1)
    return M[n, m]

def norm_names(x):
    # more names normalization can be added here
    return x.replace(".", "").lower()

names1 = ['C.J. McCollum', 'Metta World Peace', 'LeBron James', 'Stephen Curry']
names2 = ['Metta World Peace', 'Steph Curry', 'Kevin Durant', 'CJ McCollum']

names1 = list(map(norm_names, names1))
names2 = list(map(norm_names, names2))

indices = []
for i, name in enumerate(names1):
    for name2 in names2:
         indices += [i] if levenshtein_distance(name, name2) <= 2 else []

это вернет [0, 1, 3]


вы получаете ошибку из-за y в z: вы можете использовать y в w: также вы можете выполнить некоторое форматирование, например, удалить '.' перед сравнением, а затем вы можете использовать любой алгоритм схожести строк, например расстояние Левенштейна, чтобы найти похожие строки, "pip install python-Levenshtein"

import numpy as np
import Levenshtein as ld

names1 = ['C.J. McCOllum', 'Metta World Peace', 'LeBron James', 'Stephen 
Curry']

names2 = ['Metta World Peace', 'Steph Curry', 'Kevin Durant', 'CJ McCollum']
idx = np.zeros(3)
i = 0
similarity_index =3
for x, y in enumerate(names1):
y=y.replace('.','')

for z, w in enumerate(names2):
    w= w.replace('.','')
    if ld.distance(y,w) < similarity_index:
        idx[i] = x
        i = i+1


 print(idx)

Есть идеи?

10000