Python 确定列表中升序或降序停止的位置

Python 确定列表中升序或降序停止的位置,python,list,sorting,Python,List,Sorting,我有一个大的连续数据列表,我试图找出数据在哪里增加,条目数量最少,在哪里减少。例如,如果我有一个列表 [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),但它不能在单个列表中获取整个长度 关于如何解决这个问题有什么想法吗?单调无重叠: 这个版本发现单调序列,不

我有一个大的连续数据列表,我试图找出数据在哪里增加,条目数量最少,在哪里减少。例如,如果我有一个列表

[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),但它不能在单个列表中获取整个长度


关于如何解决这个问题有什么想法吗?

单调无重叠:

这个版本发现单调序列,不注册重叠;很抱歉最初没有注意到

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
在性能方面:

In [6]: timeit list(find_sequences(x))
100000 loops, best of 3: 8.44 µs per loop
In [3]: timeit list(find_sequences(x))
100000 loops, best of 3: 10.5 µs per loop
带重叠的单调/非单调:


此函数用于查找单调和重叠序列;您可以通过更改
=
轻松地将其更改为非单调工作,以下操作应该可以正常工作。。。它将数据分解为不相交的单调子序列,然后根据长度标准进行过滤

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]
def get_单调子序列(数据,最小长度):
方向=数据[1]-数据[0]#确定初始子序列的方向
子序列=[]
cur_seq=[]
对于范围内的i(0,len(数据)-1):
如果方向>0:
如果(数据[i]>=数据[i-1]):
当前顺序追加(数据[i])
其他:
子序列追加(当前顺序)
cur_seq=[数据[i]]
方向=数据[i+1]-数据[i]
其他:
如果(数据[i]0:
当前顺序追加(数据[-1])
子序列追加(当前顺序)
其他:
子序列追加(当前顺序)
子序列。追加([data[-1]])
如果len(x)>=最小长度,则返回[x表示子序列中的x]

另一方面,您的问题并不清楚,但您的输出表明,您希望从左到右贪婪地收集子序列,这是本代码假定的。

循环列表。使用变量跟踪(a)当前运行和(b)当前运行的方向。当当前运行结束时,检查它是否足够长(如果是,则输出它),然后开始新的运行。我认为最复杂的情况是当您点击第二个
8
并输出终止于此的升序运行。是否有长度为3(
13,13,8
的新运行),或运行不允许重叠?无论哪种方式,您都要在设置新运行时考虑到这一点。始终并行跟踪升序和降序运行可能会解决复杂的问题。每次运行都将停止,当升序运行的下一个数字下降时,反之亦然。我已经实现了简单和复杂的情况s、 @Dornhee,谢谢你的提示!@AFL:我很好奇,但是是什么让你选择接受哪个答案?我的意思是,我真的很想知道。
[x代表x,如果len(x)>=min_length]
会被认为是惯用的;
filter()
现在在大多数情况下都不受欢迎。我们的版本的性能似乎几乎相同:你的~8.5us,我的~9.5us!其中一个direction=-1应该是direction=1吗?@AFL-是的,这就是我的意思:P但更好的是,你的评论指出了一个更严重的错误;我没有正确处理输入结束时的方向更改。我已经更新了c带着修复的颂歌。谢谢!
[[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
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]