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

Detect and count numerical sequence in Python array

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

# 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,2,2,1] 中模式 [1,2,1] "hides" 的情况。我需要找到一种方法来减少这个重复数字序列,以便达到 [1,2,1]。有什么想法吗?

我不使用 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

希望对您有所帮助。

这是一个可以做到的单线

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。

我能想到的解决你问题的唯一方法 子模式匹配是使用 regex.

以下是findind的演示,例如list1中的序列[1,2,1]:

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