Python 从一组序列中提取长度为 X 的常见模式
Python extract common patterns of length X among a set of sequences
假设我有以下内容:
data = ['ABCD', 'ABABC', 'BCAABCD']
我正在尝试创建一个函数,它使用 Counter 接受三个 argvs,一个用于数据,第二个用于必须考虑这种模式的序列数量的最小比例,第三个那是最大的模式长度。
一个工作函数应该给我以下内容:
>>> check(data, 0.50, 2)
Counter({'A': 3, 'AB': 3, 'B': 3, 'BC': 3, 'C': 3, 'CD': 2, 'D': 2})
>>> check(data, 0.34, 4)
Counter({'A': 3, 'AB': 3, 'ABC': 3, 'ABCD': 2, 'B': 3, 'BC': 3, 'BCD': 2, 'C': 3, 'CD': 2, 'D': 2})
我真的迷失在这件事上,我只知道如何获得两个或更多字母的组合:
Counter(combinations(data[0], 2)) & Counter(combinations(data[1], 2)) & Counter(combinations(data[2], 2))
而且我也知道如何使用 :
获取数据所有元素中字母的总和
Counter(data[0]) + Counter(data[1]) + Counter(data[2])
(奇怪的是,我无法像我想做的那样使用列表理解来完成这个总和,因为一个错误说我不能在 'str' 和 'int' 之间做'+'
如果你们不能给我完整的代码,没关系,我只需要一些关于如何开始整个事情和获得逻辑的指导。
祝阅读我全部内容的人度过愉快的一天 :)
您可以使用递归生成器函数获取 data
中合并子串的所有组合(最大长度 <=
),并使用 collections.defaultdict
找到子串交集:
from collections import defaultdict
data = ['ABCD', 'ABABC', 'BCAABCD']
def combos(d, l, c = []):
if c:
yield ''.join(c)
if d and len(c) < l:
yield from combos(d[1:], l, c+[d[0]])
if not c:
yield from combos(d[1:], l, c)
def check(d, p, l):
_d = defaultdict(set)
for i in d:
for j in combos(i, l):
_d[j].add(i)
return {a:len(b) for a, b in _d.items() if len(b)/len(d) >= p}
print(check(data, 0.50, 2))
print(check(data, 0.34, 4))
输出:
{'A': 3, 'AB': 3, 'B': 3, 'BC': 3, 'C': 3, 'CD': 2, 'D': 2}
{'A': 3, 'AB': 3, 'ABC': 3, 'ABCD': 2, 'B': 3, 'BC': 3, 'BCD': 2, 'C': 3, 'CD': 2, 'D': 2}
假设我有以下内容:
data = ['ABCD', 'ABABC', 'BCAABCD']
我正在尝试创建一个函数,它使用 Counter 接受三个 argvs,一个用于数据,第二个用于必须考虑这种模式的序列数量的最小比例,第三个那是最大的模式长度。
一个工作函数应该给我以下内容:
>>> check(data, 0.50, 2)
Counter({'A': 3, 'AB': 3, 'B': 3, 'BC': 3, 'C': 3, 'CD': 2, 'D': 2})
>>> check(data, 0.34, 4)
Counter({'A': 3, 'AB': 3, 'ABC': 3, 'ABCD': 2, 'B': 3, 'BC': 3, 'BCD': 2, 'C': 3, 'CD': 2, 'D': 2})
我真的迷失在这件事上,我只知道如何获得两个或更多字母的组合:
Counter(combinations(data[0], 2)) & Counter(combinations(data[1], 2)) & Counter(combinations(data[2], 2))
而且我也知道如何使用 :
Counter(data[0]) + Counter(data[1]) + Counter(data[2])
(奇怪的是,我无法像我想做的那样使用列表理解来完成这个总和,因为一个错误说我不能在 'str' 和 'int' 之间做'+'
如果你们不能给我完整的代码,没关系,我只需要一些关于如何开始整个事情和获得逻辑的指导。
祝阅读我全部内容的人度过愉快的一天 :)
您可以使用递归生成器函数获取 data
中合并子串的所有组合(最大长度 <=
),并使用 collections.defaultdict
找到子串交集:
from collections import defaultdict
data = ['ABCD', 'ABABC', 'BCAABCD']
def combos(d, l, c = []):
if c:
yield ''.join(c)
if d and len(c) < l:
yield from combos(d[1:], l, c+[d[0]])
if not c:
yield from combos(d[1:], l, c)
def check(d, p, l):
_d = defaultdict(set)
for i in d:
for j in combos(i, l):
_d[j].add(i)
return {a:len(b) for a, b in _d.items() if len(b)/len(d) >= p}
print(check(data, 0.50, 2))
print(check(data, 0.34, 4))
输出:
{'A': 3, 'AB': 3, 'B': 3, 'BC': 3, 'C': 3, 'CD': 2, 'D': 2}
{'A': 3, 'AB': 3, 'ABC': 3, 'ABCD': 2, 'B': 3, 'BC': 3, 'BCD': 2, 'C': 3, 'CD': 2, 'D': 2}