使用模式阈值识别单词列表中的模式
Identify patterns within list of words with pattern threshold
正在研究 Python 中的模式识别功能,假设 return 带有计数器的模式数组
让我们想象一个字符串列表:
m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']
在高层,我想回复的是:
Pattern | Count
----------------
AB | 6
ABB | 4
BC | 3
----------------
问题:据我所知,模式以 2 个字符开头并且是每个字符串值的前导字符(即 XXZZZ、XXXZZZ(其中 XX 是我正在寻找的模式))。我希望能够将模式的最小长度参数化为函数的输入,以优化 运行 时间。
PS。列表中的每一项都是一个单词。
我的问题是我需要从阈值开始对每个字母进行迭代,但我被困在那里了。
我更喜欢使用 startswith('AB')
首先,让我们定义您的字符串:
>>> 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])
为了与您的 table 进行比较,以下是三个最常见的前导字符串:
>>> 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)]
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)
您可以使用函数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)]
正在研究 Python 中的模式识别功能,假设 return 带有计数器的模式数组
让我们想象一个字符串列表:
m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']
在高层,我想回复的是:
Pattern | Count
----------------
AB | 6
ABB | 4
BC | 3
----------------
问题:据我所知,模式以 2 个字符开头并且是每个字符串值的前导字符(即 XXZZZ、XXXZZZ(其中 XX 是我正在寻找的模式))。我希望能够将模式的最小长度参数化为函数的输入,以优化 运行 时间。
PS。列表中的每一项都是一个单词。
我的问题是我需要从阈值开始对每个字母进行迭代,但我被困在那里了。 我更喜欢使用 startswith('AB')
首先,让我们定义您的字符串:
>>> 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])
为了与您的 table 进行比较,以下是三个最常见的前导字符串:
>>> 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)]
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)
您可以使用函数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)]