Определить шаблоны в списке слов с порогом шаблона - PullRequest
2 голосов
/ 19 сентября 2019

Работа над функцией распознавания образов в Python, которая предполагает возврат массива образцов со счетчиком

Давайте представим список строк:

m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

на высоком уровне,то, что я хотел бы получить обратно:

Pattern | Count
----------------
   AB   |   6
  ABB   |   4
   BC   |   3
----------------

Проблема: все, что я знаю, это то, что шаблоны начинаются с 2 символов и являются ведущими символами для каждого строкового значения (т.е. XXZZZ, XXXZZZ (где XX - это шаблон, которыйЯ ищу)).Я хотел бы иметь возможность параметризовать минимальную длину шаблона в качестве входа функции для оптимизации времени выполнения.

PS.каждый элемент в списке уже состоит из одного слова.

Моя проблема в том, что мне нужно выполнить итерацию для каждой буквы, начиная с порога, и я застреваю там.Я бы предпочел использовать стартс с ('AB')

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Во-первых, давайте определим вашу строку:

>>> m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

Теперь давайте посчитаем количество всех ведущих строк длиной 2 или 3:

>>> from collections import Counter
>>> c = Counter([s[:2] for s in m] + [s[:3] for s in m if len(s)>=3])

Для сравнения с вашей таблицей,Вот три наиболее распространенных ведущих строки:

>>> c.most_common(3)
Out[15]: [('AB', 6), ('ABB', 4), ('BC', 3)]

Обновление

Чтобы включить все ключи вплоть до длины len(max(m, key=len))-1:

>>> n = len(max(m, key=len))
>>> c = Counter(s[:i] for s in m for i in range(2, min(n, 1+len(s))))

Дополнительный тест

Чтобы продемонстрировать, что мы правильно работаем с более длинными строками, давайте рассмотрим другой ввод:

>>> m = ['ab', 'abc', 'abcdef']
>>> n = len(max(m, key=len))
>>> c = Counter(s[:i] for s in m for i in range(2, min(n, 1+len(s))))
>>> c.most_common()
[('ab', 3), ('abc', 2), ('abcd', 1), ('abcde', 1)]
0 голосов
/ 19 сентября 2019

Вы можете использовать функцию accumulate() для генерации накопленных строк и функцию islice() для получения строк минимальной длины:

from itertools import accumulate, islice
from collections import Counter

m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

c = Counter()
for i in map(accumulate, m):
    c.update(islice(i, 1, None)) # get strings with a minimal length of 2

print(c.most_common(3))
# [('AB', 6), ('ABB', 4), ('BC', 3)]
0 голосов
/ 19 сентября 2019

Использование collection.Counter

counter = collections.Counter()
min_length = 2
max_length = len(max(m, key=len))
for length in range(min_length, max_length):
    counter.update(word[:length] for word in m if len(word) >= length)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...