найти, какая строка в списке ближе всего к символу - PullRequest
0 голосов
/ 31 января 2020

У меня есть PDF-документ, который я проанализировал в списке, например:

listTxt = ['met een motor, losse delen van caravans, losse delen van ',
           'aanhangwagens die in uw woonhuis, schuur of garage op ',
           'hetzelfde adres staan tot maximaal € 1.250,-.',
           ' ',
           ' horen deze losse delen bij een bedrijf? Of zijn ze bedoeld ',
           'aanhangwagens die niet kapot zijn verzekerd',  '• Schade door grondwater dat onverwacht het woonhuis ',
           'binnenstroomt door afvoerleidingen en apparaten die daarop ',
           'zijn aangesloten.',
           '• Schade door water dat uit een aquarium stroomt als het ',
           'aquarium onverwacht kapot is gegaan. We betalen ook voor de ',
           'inhoud van het aquarium tot maximaal € 1.250,-.',
           '• Schade door water dat uit een waterbed stroomt. Maar alleen als ',
           'het waterbed onverwacht kapot is gegaan.']

Теперь я хочу вернуть строку, ближайшую (на расстоянии) к символу евро (€). Я рассмотрел различные алгоритмы, такие как расстояние Левенштейна и др. c., Но моя задача на самом деле довольно проста, и это расстояние может быть просто числом символов.

Цикл с условным видом работает:

for t in list:
    if 'aanhangwagens' and '€' in t:
        print(t)

Результат:

hetzelfde adres staan tot maximaal € 1.250,-.
inhoud van het aquarium tot maximaal € 1.250,-.

Но я хочу, чтобы 'aanhangwagens' в listTxt [1] действительно был близок к следующему тексту listTxt [2] (со знаком €), поэтому желаемый результат :

'aanhangwagens die in uw woonhuis, schuur of garage op ', 'hetzelfde adres staan tot maximaal € 1.250,-.'

для фразы аквариум, она отлично работает, потому что аквариум и € находятся в одной строке, т.е. listTxt[11]

'hetzelfde adres staan tot maximaal € 1.250,-.'

Ответы [ 2 ]

1 голос
/ 31 января 2020

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

import numpy as np


listTxt = ['met een motor, losse delen van caravans, losse delen van ',
           'aanhangwagens die in uw woonhuis, schuur of garage op ',
           'hetzelfde adres staan tot maximaal € 1.250,-.',
           ' ',
           ' horen deze losse delen bij een bedrijf? Of zijn ze bedoeld ',
           'aanhangwagens die niet kapot zijn verzekerd',  '• Schade door grondwater dat onverwacht het woonhuis ',
           'binnenstroomt door afvoerleidingen en apparaten die daarop ',
           'zijn aangesloten.',
           '• Schade door water dat uit een aquarium stroomt als het ',
           'aquarium onverwacht kapot is gegaan. We betalen ook voor de ',
           'inhoud van het aquarium tot maximaal € 1.250,-.',
           '• Schade door water dat uit een waterbed stroomt. Maar alleen als ',
           'het waterbed onverwacht kapot is gegaan.']

euro = np.array([string.count('€') for string in listTxt])
ahw = np.array([string.count('aanhangwagen') for string in listTxt])

all_values = np.add(euro,ahw)


score = []
matches = []
for i, value in enumerate(all_values):
    if value > 0:
        score.append(value)
        matches.append(listTxt[i])
    elif score:
        print(sum(score), matches)
        score = []
        matches = []

Он подсчитывает количество раз, когда '€' или 'aanhangwagen' встречается в каждом предложении, а затем суммирует результат. Затем сделайте небольшое l oop, которое находит группы «близких» значений между нулями.

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

В этом случае, результат будет:

2 ['aanhangwagens die in uw woonhuis, schuur of garage op ', 'hetzelfde adres staan tot maximaal € 1.250,-.']
1 ['aanhangwagens die niet kapot zijn verzekerd']
1 ['inhoud van het aquarium tot maximaal € 1.250,-.']

Что вы хотели!

1 голос
/ 31 января 2020

По вашему определению я написал что-то, что ищет близкие строки, содержащие определенные символы. Для начала нужно вычислить два списка "resa" и "rese". Они сообщают, содержится ли данная строка в вашем списке. Например, если вы ищете «a» в списке [«ab c», «ccd», «efg», «agf»], результирующий список будет [1,0,0,1]. Вы должны рассчитать их для «aanhangwagens» и символа евро. С помощью этих списков вы можете проверить расстояния между 1 в списке евро и 1 в списке «aanhangwagens».

В вашем примере поиск «aanhangwagens» дает: [0, 1, 0, 0 , 0, 1, 0, 0, 0, 0, 0, 0, 0, 0] и евро дает: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 , 0, 0]

Алгоритм, который я написал, сохраняет самую близкую строку, НО, если две строки имеют одинаковое расстояние, он поместит их в список результатов обоих. Пожалуйста, перед использованием этого кода запустите несколько тестов, я не могу заверить вас, что он будет работать в любом случае.

resa=[]
rese=[]
for t in listTxt:
    if 'aanhangwagens' in t:
        resa.append(1)
    else:
        resa.append(0)
    if '€' in t:
        rese.append(1)
    else:
        rese.append(0)

def close_line(aliste, alista, alistTxt):
    all_closest_lines=[]
    for i in range(len(aliste)):
        if(aliste[i]==0):
            continue
        else:
            closest_line=[]
            amin=max(len(aliste), len(alista))
            for j in range(len(alista)):
                if(alista[j]==0):
                    continue
                else:
                    if(abs(i-j)<amin):
                        amin=abs(i-j)
                        closest_line=[]
                        closest_line.append([alistTxt[j], "Closest to € in position{}".format(i)])
                    elif(abs(i-j)==amin):
                        closest_line.append([alistTxt[j], "Closest to € in position{}".format(i)])
            all_closest_lines+=closest_line
    return(all_closest_lines)

print(close_line(rese, resa, listTxt))

Результаты:

[['aanhangwagens die in uw woonhuis, schuur of garage op ', 'Closest to € in position2'], ['aanhangwagens die niet kapot zijn verzekerd', 'Closest to € in position11']]
...