Python: группировка похожего текста из списка - PullRequest
0 голосов
/ 06 июня 2018

как я могу сгруппировать значения из массива с нечеткой логикой, соответствующей 80%

combined_list = ['magic', 'simple power', 'matrix', 'simple aa', 'madness', 'magics', 'mgcsa', 'simple pws', 'seek', 'dour', 'softy'] 

выход:

['magic, magics'], ['simple pws', 'simple aa'], ['simple power'], [matrix]

вот что я достиг, но сильно отличается от моегоЦель.Кроме того, он поддерживает только несколько значений, и я планирую запустить его с 50 000 записей

from difflib import SequenceMatcher as sm

combined_list = ['magic', 'simple power', 'matrix', 'madness', 'magics', 'mgcsa', 'simple pws', 'seek', 'sour', 'soft']
result = list()
result_group = list()

for x in combined_list:

    for name in combined_list:
        if(sm(None, x, name).ratio() >= 0.80):
            result_group.append(name)
        else:
            pass

    result.append(result_group)
    print(result)
    del result_group[:]


print(result)

результат печати вне цикла пуст, но результат внутри цикла содержит значения, которые мне нужны.хотя вывод отличается от того, что мне нужно

['magic', 'magics']]
[['simple power', 'simple pws'], ['simple power', 'simple pws']]
[['matrix'], ['matrix'], ['matrix']]
[['madness'], ['madness'], ['madness'], ['madness']]
[['magic', 'magics'], ['magic', 'magics'], ['magic', 'magics'], ['magic', 'magics'], ['magic', 'magics']]
[['mgcsa'], ['mgcsa'], ['mgcsa'], ['mgcsa'], ['mgcsa'], ['mgcsa']]
[['simple power', 'simple pws'], ['simple power', 'simple pws'], ['simple power', 'simple pws'], ['simple power', 'simple pws'], ['simple power', 'simple pws'], ['simple power', 'simple pws'], ['simple power', 'simple pws']]
[['seek'], ['seek'], ['seek'], ['seek'], ['seek'], ['seek'], ['seek'], ['seek']]
[['sour'], ['sour'], ['sour'], ['sour'], ['sour'], ['sour'], ['sour'], ['sour'], ['sour']]
[['soft'], ['soft'], ['soft'], ['soft'], ['soft'], ['soft'], ['soft'], ['soft'], ['soft'], ['soft']]
[['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa'], ['simple aa']]

[[], [], [], [], [], [], [], [], [], [], []]

Ответы [ 3 ]

0 голосов
/ 06 июня 2018
from difflib import SequenceMatcher as sm

combined_list = ['magic', 'simple power', 'matrix', 'madness', 'magics', 'mgcsa', 'simple pws', 'seek', 'sour', 'soft']
combined_list.sort()


def getPairs(combined_list):
    results = list()
    grouped = set()
    for x in combined_list:
        result_group = list()
        if(grouped.__contains__(x)):
            continue
        for name in combined_list:
            if(sm(None, x, name).ratio() >= 0.80):
                result_group.append(name)
                grouped.add(name);
            else:
                pass;

        results.append(result_group)
    return results;

print(getPairs(combined_list))
0 голосов
/ 06 июня 2018
from difflib import SequenceMatcher as sm

combined_list = ['magic', 'simple power', 'matrix', 'madness', 'magics', 
'mgcsa', 'simple pws', 'seek', 'sour', 'soft']
result = list()
result_group = list()
usedElements = list()
skip = False

for firstName in combined_list:
    skip = False

    for x in usedElements:
        if x == firstName:
            skip = True
    if skip == True:
        continue

    for secondName in combined_list:

        if(sm(None, firstName, secondName).ratio() >= 0.80):            

            result_group.append(secondName)
            usedElements.append(secondName)
        else:
            pass

    result.append(result_group[:])
    del result_group[:]

print(result)

Я добавил способ удаления дубликатов, выбрасывая элементы из списка, которые уже помещены в группу, в список usedElements.

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

    if len(result_group) > 1:
        result.append(result_group[:])
        del result_group[:]
    del result_group[:]

print(result)

Надеюсь, это поможет.

0 голосов
/ 06 июня 2018

Проблема в следующих строках:

result.append(result_group)
print(result)
del result_group[:]

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

result.append(result_group[:])
print(result)
del result_group[:]

Или не удаляйте элементы списка, а создайте новый список для каждой итерации:

for x in combined_list:
    result_group = []
    for name in combined_list:
        ...

result.append(result_group)

Редактировать :Если вы хотите избавиться от дубликатов, попробуйте использовать набор вместо списка:

# result = list()
result = set([])

...
# result.append(result_group)
result.add(tuple(result_group))

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

Edit2 : Собрать все вместе и проверить фактические группы из 2+ участников:

from difflib import SequenceMatcher as sm

combined_list = ['magic', 'simple power', 'matrix', 'madness',
                 'magics', 'mgcsa', 'simple pws', 'seek', 'sour', 'soft']

# using a set ensures there are no duplicates
result = set([])

for x in combined_list:
    result_group = []
    for name in combined_list:
        if(sm(None, x, name).ratio() >= 0.80):
            result_group.append(name)

    if len(result_group) > 1: # this gets rid of single-word groups
        result.add(tuple(result_group))

print(result)
...