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]