4

連続データの大きなリストがあり、最小量のエントリに対してデータが増加する場所と減少する場所を把握しようとしています。たとえば、リストがある場合

[0, 1, 3, 8, 10, 13, 13, 8, 4, 11, 5, 1, 0]

0、1、3、8、10、13、13、および 11、5、1、0 の実行をキャプチャできるようにしたいのですが、8、4 の実行はキャプチャできません (任意の量 3 より小さいため)。

現在、昇順および降順の関数を使用して、一度に特定の数の実行 (たとえば、0、1、3、および 1、3、8) をキャプチャしていますが、単一のリストで全長を取得することはできません。 .

この問題を解決する方法についてのアイデアはありますか?

4

2 に答える 2

2

オーバーラップのない単調:

このバージョンは、単調なシーケンスを検出し、オーバーラップを登録しません。最初に注意を払わなかったことをお詫びします。

def find_sequences(lst, min_len=3):
    curr = []
    asc = None
    for i in lst:
        if not curr or len(curr) == 1 or asc and i >= curr[-1] or not asc and i <= curr[-1]:
            if len(curr) == 1:
                asc = curr[-1] < i
            curr.append(i)
        else:
            if len(curr) >= min_len:
                yield curr
            asc = None
            curr = [i]
    if len(curr) >= min_len:
        yield curr

収量:

[[0, 1, 3, 8, 10, 13, 13], [11, 5, 1, 0]]

パフォーマンスで:

In [6]: timeit list(find_sequences(x))
100000 loops, best of 3: 8.44 µs per loop

オーバーラップのある単調/非単調:

この関数は、単調で重複するシーケンスを見つけます。を と に>=それぞれ変更することで非単調に動作するように簡単に変更できます。また、パラメーター化することもできます。<=><

def find_sequences(lst, min_len=3):
    asc, desc = [], []
    for i in lst:
        if not asc or i >= asc[-1]:
            asc.append(i)
        else:
            if len(asc) >= min_len:
                yield asc
            asc = [i]

        if not desc or i <= desc[-1]:
            desc.append(i)
        else:
            if len(desc) >= min_len:
                yield desc
            desc = [i]

    if len(desc) >= min_len:
        yield desc
    if len(asc) >= min_len:
        yield asc

収量:

[[0, 1, 3, 8, 10, 13, 13], [13, 13, 8, 4], [11, 5, 1, 0]]

パフォーマンスで:

In [3]: timeit list(find_sequences(x))
100000 loops, best of 3: 10.5 µs per loop
于 2013-10-02T17:30:52.780 に答える
1

以下は機能するはずです...データをばらばらな単調なサブシーケンスに分割し、長さの基準でフィルタリングします。

def get_monotonic_subsequences(data, min_length):
    direction = data[1] - data[0] #determine direction of initial subsequence
    subsequences = []
    cur_seq = []
    for i in range(0, len(data) - 1):
        if direction > 0:
            if (data[i] >= data[i-1]):
                cur_seq.append(data[i])
            else:
                subsequences.append(cur_seq)
                cur_seq = [data[i]]
                direction = data[i+1] - data[i]
        else:
            if (data[i] <= data[i-1]):
                cur_seq.append(data[i])
            else:
                subsequences.append(cur_seq)
                cur_seq = [data[i]]
                direction = data[i+1] - data[i]

    if  (data[-1] - data[-2])*direction > 0:
        cur_seq.append(data[-1])
        subsequences.append(cur_seq)
    else:
        subsequences.append(cur_seq)
        subsequences.append([data[-1]])
    return [x for x in subsequences if len(x) >= min_length]

余談ですが、質問からは明確ではありませんが、出力は、サブシーケンスが左から右に貪欲に収集されることを期待していることを示唆しています。これは、このコードが想定しています。

于 2013-10-02T17:45:05.737 に答える