2016-09-29 3 views
-1

数値シーケンス(たとえば1次元配列)では、異なるパターンの数字を見つけて、それぞれの結果を別々に数えたいと思う。しかし、数字は繰り返し発生することがありますが、基本パターンだけが重要です。Python配列の数値シーケンスを検出してカウントする

# 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 

私は私に検索されたパターンのインデックスを与えるクヌース - モリス - プラットの文字列マッチング(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

"パターン" を構成するもの?あなたの問題は非常に幅広く聞こえる。 –

+1

問題の解決方法を示してください。 –

+0

は、あなたが探しているパターンはあらかじめ定義されていますか?またはあなたはトリプレットのすべての可能なパターンを見つけたいですか? – armak

答えて

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 

を助けるかもしれない希望。ここで

+0

あなたの貢献に感謝しますが、コードは、特定の数字が何回も繰り返されるバージョンよりも、シグナルの正確なパターンだけを見つけるようです。例:パターン[1,2,1]は信号[1,1,2,2,2,1,1]にも存在しなければならず、 "1から2への遷移"だけが重要であり、見つけられた。これは、検出されたイベントとしてもカウントされます。これらのケースも見つかるように、コードに追加する方法はありますか? – NumbThumb

+0

真ん中にダブルナンバーを無視するバージョンを追加しました。 – JBecker

+0

ニース、これは仕事です!とても有難い! :) – NumbThumb

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を合計します。

+0

パターンpは配列aで2回見つかるはずです。シーケンス[1,2,1]はまた、信号の[1,2,2,2,2,1]に「隠す」。あなたの提案はちょうど私が正しい場合は一度シーケンスを見つけますか? – NumbThumb

+0

はい、これはあなたが入力した正確なパターンに一致し、パターンの1つの部分の任意の数の繰り返しは一致しません。 –

+0

何も繰り返しは起こらないように信号を減らすことができ、 "隠された"パターンも見いだすことができますか?これは問題を解決するだろう。 ;) – NumbThumb

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'] 
関連する問題