检测并计算 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']
在数字序列(例如一维数组)中,我想找到不同的数字模式并分别计算每个发现。然而,数字可以重复出现,但只有基本模式很重要。
# 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']