检测并计算Python数组中的数字序列

时间:2016-09-29 11:51:39

标签: python arrays numbers detection

在数字序列(例如一维数组)中,我想找到不同的数字模式,并分别计算每个发现。但是,数字可以重复出现,但只有基本模式很重要。

# 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]。有什么想法吗?

3 个答案:

答案 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']