Python код для извлечения похожих строк из 2 списков - PullRequest
0 голосов
/ 09 февраля 2020

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

names1 = ['C.J. 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 код среди всех итераций names2 и выводит индекс записи, аналогичный записи в names2. idx - список, который должен содержать индекс похожих строк. i является индексом idx. Каждый раз, когда обнаруживается подобная строка, она сохраняется в idx и i увеличивается на 1, так что следующая найденная запись будет записана в индексе i+1 из idx.

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

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

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

Ответы [ 2 ]

1 голос
/ 09 февраля 2020

вы получаете ошибку из-за y в z: вы можете использовать y в w: также вы можете выполнить некоторое форматирование, например, удалить '.' перед сравнением, а затем вы можете использовать любое сходство строк al go, например расстояние Левенштейна, чтобы найти похожие строки, "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)
0 голосов
/ 09 февраля 2020

Вот попытка (здесь я посчитал, что только такие изменения, как М. C = М C, использование мажульских и крошечных и расстояние Левенштейна, меньшее 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]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...