Python或R,有效地将时间序列分割成Z字形

Python或R,有效地将时间序列分割成Z字形,python,r,pandas,maxima,minima,Python,R,Pandas,Maxima,Minima,如果我有清单 l = [0, 0, 1, 2, 2, 2, 1, -1, -1, -1, 0] 我希望得到三个之字形,一个之字形被定义为局部最大值(可以是高原)和最小值(可以是山谷),如下所示,有3个之字形,a、B、C,而a和B在高原重叠,B和C在山谷重叠 A = [0, 0, 1, 2, 2, 2] B = [2, 2, 2, 1, -1, -1, -1] C = [-1, 0] 一般Python的解决方案,请注意,l可以是任何迭代器,并且只扫描一次 l = [0, 0, 1, 2, 2,

如果我有清单

l = [0, 0, 1, 2, 2, 2, 1, -1, -1, -1, 0]
我希望得到三个之字形,一个之字形被定义为局部最大值(可以是高原)和最小值(可以是山谷),如下所示,有3个之字形,a、B、C,而a和B在高原重叠,B和C在山谷重叠

A = [0, 0, 1, 2, 2, 2]
B = [2, 2, 2, 1, -1, -1, -1]
C = [-1, 0]

一般Python的解决方案,请注意,
l
可以是任何迭代器,并且只扫描一次

l = [0, 0, 1, 2, 2, 2, 1, -1, -1, -1, 0]

def zigzag(l):
    if not l:
        return []

    last = l[0]

    # the elements in current rise    
    current_rise = []

    # the elements in current drop
    current_drop  = []

    # return value
    zigzags = []

    # iterate over elements
    for i in l:
        # if we are growing...
        if i > last:
            # and the current_drop is longer than
            # current rise, then we just stopped a drop
            if len(current_drop) > len(current_rise):
                zigzags.append(current_drop)

            # in any case, a new drop can start here.
            current_drop = [i]

        else:
            # else just accumulate a current drop
            current_drop.append(i)

        # same for the other direction
        if i < last:
            if len(current_rise) > len(current_drop):
                zigzags.append(current_rise)

            current_rise = [i]

        else:
            current_rise.append(i)

        last = i

    # add the final segment    
    if len(current_rise) > len(current_drop):
        zigzags.append(current_rise)
    else:
        zigzags.append(current_drop)

    return zigzags

print zigzag(l)
# result [[0, 0, 1, 2, 2, 2], [2, 2, 2, 1, -1, -1, -1], [-1, -1, -1, 0]]
l=[0,0,1,2,2,2,1,-1,-1,-1,0]
def之字形(l):
如果不是l:
返回[]
last=l[0]
#当前经济增长的因素
当前_上升=[]
#当前版本中的元素会下降
当前_下降=[]
#返回值
之字形=[]
#迭代元素
对于l中的i:
#如果我们在成长。。。
如果我>上次:
#并且当前的_下降比
#电流上升,然后我们停止下降
如果len(电流下降)>len(电流上升):
锯齿形追加(当前_删除)
#在任何情况下,新的下降都可以从这里开始。
当前_下降=[i]
其他:
#否则就累积电流下降
当前_drop.append(i)
#另一个方向也一样
如果我是最后一个:
如果len(电流上升)>len(电流下降):
锯齿形追加(当前上升)
当前_上升=[i]
其他:
本期追加(一)
last=i
#添加最后一段
如果len(电流上升)>len(电流下降):
锯齿形追加(当前上升)
其他:
锯齿形追加(当前_删除)
返回之字形
打印之字形(l)
#结果[[0,0,1,2,2,2],[2,2,2,1,-1,-1],-1,-1,0]]

我想你需要把这个问题说得更具体一些。你只是要求通用算法来做这件事吗?你尝试过什么吗?我想知道是否有任何脱离自我的Python或R包已经做到了这一点,或者有任何快速的几行算法可以做到这一点。这可能会让你从R开始:?嗨,@JoshuaUlrich我尝试过TTR::ZigZag,但对于时间序列,我有,它有时会在高原的中间分割终点。而且,如果我没有错,它会插值,它不会给出最小值和最大值的索引。嗨,如果我们有
l=[1,0,1,0]
,这个算法似乎会失败,我认为
如果len(当前下降)>len(当前上升):
需要更改为
如果len(当前下降)>=len(当前上升)和len(当前下降)>1和当前下降[0]当前_-drop[-1]:
与其他
if