在数字序列(例如一维数组)中,我想找到不同的数字模式,并分别计算每个发现。但是,数字可以重复出现,但只有基本模式很重要。
# Example signal (1d array)
a = np.array([1,1,2,2,2,2,1,1,1,2,1,1,2,3,3,3,3,3,2,2,1,1,1])
# Search for these exact following "patterns": [1,2,1], [1,2,3], [3,2,1]
# Count the number of pattern occurrences
# [1,2,1] = 2 (occurs 2 times)
# [1,2,3] = 1
# [3,2,1] = 1
我想出了Knuth-Morris-Pratt字符串匹配(http://code.activestate.com/recipes/117214/),它给出了搜索模式的索引。
for s in KnuthMorrisPratt(list(a), [1,2,1]):
print('s')
问题是,我不知道如何找到案例,其中模式[1,2,1]“隐藏”在序列[1,2,2,2,1]中。我需要找到一种减少重复数字序列的方法,以便得到[1,2,1]。有什么想法吗?
答案 0 :(得分:2)
我不使用NumPy而且我对Python很陌生,因此可能会有更好更有效的解决方案。
我会写一个这样的函数:
def dac(data, pattern):
count = 0
for i in range(len(data)-len(pattern)+1):
tmp = data[i:(i+len(pattern))]
if tmp == pattern:
count +=1
return count
如果您想忽略模式中间的重复数字:
def dac(data, pattern):
count = 0
for i in range(len(data)-len(pattern)+1):
tmp = [data[i], data [i+1]]
try:
for j in range(len(data)-i):
print(i, i+j)
if tmp[-1] != data[i+j+1]:
tmp.append(data[i+j+1])
if len(tmp) == len(pattern):
print(tmp)
break
except:
pass
if tmp == pattern:
count +=1
return count
希望这可能会有所帮助。
答案 1 :(得分:1)
这是一个可以做到的单行
import numpy as np
a = np.array([1,1,2,2,2,2,1,1,1,2,1,1,2,3,3,3,3,3,2,2,1,1,1])
p = np.array([1,2,1])
num = sum(1 for k in
[a[j:j+len(p)] for j in range(len(a) - len(p) + 1)]
if np.array_equal(k, p))
最里面的部分是列表推导,它生成与模式长度相同的所有数组。对于此列表中与模式匹配的每个元素,外部部分总和1.
答案 2 :(得分:1)
我能想到解决问题的唯一方法
子模式匹配是使用regex
。
以下是findind的演示,例如[1,2,1]
中的序列list1
:
import re
list1 = [1,1,2,2,2,2,1,1,1,2,1,1,2,3,3,3,3,3,2,2,1,1,1]
str_list = ''.join(str(i) for i in list1)
print re.findall(r'1+2+1', str_list)
这将为您提供结果:
>>> print re.findall(r'1+2+1', str_list)
['1122221', '1121']