web-dev-qa-db-ja.com

リストからパターンを見つける

私は現在、整数のリストでパターンを見つける方法を探していますが、私が使用する方法は、もちろん、異なる要素を持つ文字列や他のリストに適用できます。今私が探しているものを説明しましょう。

整数のリストで最も長い繰り返しパターンを見つけたい。例えば、

[1, 2, 3, 4, 1, 2, 3]
# This list would give 1, 2, 3

重複するパターンは破棄する必要があります。 ( 特定されません )

[1, 1, 1, 1, 1]
# Should give 1, 1  Not 1, 1, 1, 1

これは私を助けなかったものです

リスト内のパターンの検索 (最初の回答の背後にあるロジックは理解できませんでしたが、説明はほとんどありません。2番目の回答は、パターンが既知である場合にのみ問題を解決します。)

リストから整数パターンを検索 (パターンが指定され、出現回数が必要です。私の質問とは異なります。)

最も長い一般的なサブシーケンスの問題 (ほとんどの人がこの問題に対処しましたが、私の問題とはほど遠いです。パターンを検索するときに連続する要素が必要です。ただし、この場合、個別の要素もサブシーケンスとしてカウントされます。)

ここで私が試したもの

def pattern(seq):
    n = len(seq)
    c = defaultdict(int) # Counts of each subsequence
    for i in xrange(n):
        for j in xrange(i + 1, min(n, n / 2 + i)): 
            # Used n / 2 because I figured if a pattern is being searched
            # It cant be longer that the half of the list.
            c[Tuple(seq[i:j])] += 1      
    return c

ご覧のように、すべてのサブリストを見つけて、繰り返しをチェックします。私はこのアプローチが少し素朴(そして非効率的)であることを発見し、より良い方法を必要としています。私を助けてください。前もって感謝します。

注1:リストは事前に決定されていますが、アルゴリズムが失敗したため、コンピューターをフリーズする前にリストの一部しかチェックできません。したがって、私が見つけようとしているパターンは、検索リストの半分よりも非常に長くなる可能性があります。元のリストの一部のみを検索しているため、検索リスト自体よりも長くなる可能性があります。私は使用しています。元のリストの大部分を検索できるので、パターンを見つける可能性が高くなります。 (ある場合)。

注2:自分でテストする場合のリストの一部を次に示します。実際にパターンがあるように見えますが、信頼できるコードでテストする前に確信が持てません。 サンプルリスト

注3:私はデータマイニングの深刻な問題としてこれに取り組みます。長い説明をすると習得しようとします。これはLCSよりもはるかに重要な問題のように思われますが、LCSの方がはるかに人気があります。Dこの方法を見つけようとしているのは、科学者がDNAパターンを見つけるために使用する方法のようです。

19
Max Paython

コード

「オーバーラップしない」という要件を無視して、使用したコードは次のとおりです。

def pattern(seq):
        storage = {}
        for length in range(1,len(seq)/2+1):
                valid_strings = {}
                for start in range(0,len(seq)-length+1):
                        valid_strings[start] = Tuple(seq[start:start+length])
                candidates = set(valid_strings.values())
                if len(candidates) != len(valid_strings.values()):
                        print "Pattern found for " + str(length)
                        storage = valid_strings
                else:
                        print "No pattern found for " + str(length)
                        return set(filter(lambda x: storage.values().count(x) > 1, storage.values()))
        return storage

これを使用して、データセット内に長さ303の8つの異なるパターンを見つけました。プログラムもかなり高速に実行されました。

疑似コードバージョン

define patterns(sequence):
    list_of_substrings = {}
    for each valid length:  ### i.e. lengths from 1 to half the list's length
        generate a dictionary my_dict of all sub-lists of size length
        if there are repeats:
            list_of_substrings = my_dict
        else:
            return all repeated values in list_of_substrings
    return list_of_substrings  #### returns {} when there are no patterns
5
Naveen Arun

答えがあります。できます。 (オーバーラップなし)しかし、それはpython3用です

      def get_pattern(seq):
        seq2=seq
        outs={}
        l=0
        r=0
        c=None
        for end in range(len(seq2)+1):
          for start in range(end):
            Word=chr(1).join(seq2[start:end])
            if not Word in outs:
              outs[Word]=1
            else:
              outs[Word]+=1
        for item in outs:
          if outs[item]>r or (len(item)>l and outs[item]>1):
            l=len(item)
            r=outs[item]
            c=item
        return c.split(chr(1))
0
Glitching247