How to detect up and down trend in a list?

Question:

A lot of python list with some data, how to detect the data in the list is meet downward then upward.
For example:

a1 = [8,6,4,1,-2,-6,5,8,9,87] 
a2 = [8,6,4,1,-2,-6,5,-8,9,10]

where data in a1 is downard then upward,expect print ‘OK’
but data in a2 is downard then upward then downard last upward, expect print ‘NG’
how to do it by python?

Asked By: baliao

||

Answers:

You can iterate through the list three items at a time and count the types of peaks that you see, either downward or upwards. At the end, return True if there is only one downward peak, False otherwise.

def one_downward_peak(data):
    upward_peaks = 0
    downward_peaks = 0

    for i in range(len(data) - 2):
        a, b, c = data[i:i+3]
        if a > b < c:
            downward_peaks += 1
        elif a < b > c:
            upward_peaks += 1

    return upward_peaks == 0 and downward_peaks == 1
>>> one_downward_peak([8,6,4,1,-2,-6,5,8,9,87])
True
>>> one_downward_peak([8,6,4,1,-2,-6,5,-8,9,10])
False

If you want to optimize this, you could exit early as soon as you see an upward peak.

Answered By: flakes

You can compute the sign of the successive differences, then only keep the different ones. If this yields [-1, 1] this is a OK, else a NG:

import numpy as np

def check(lst):
    # sign of successive difference
    s = np.sign(np.diff(lst))
    # mask to deduplicate successive values
    m1 = np.r_[True, s[:-1]!=s[1:]]
    # mask to remove flat lines
    m2 = s != 0
    # OK if both masks are True else NG
    return 'OK' if s[m1&m2].tolist() == [-1, 1] else 'NG'

check(a1)
# 'OK'

check(a2)
# 'NG'

check([2,1,1,2])
# 'OK'

Intermediates:

### first example

lst
# [8, 6, 4, 1, -2, -6, 5, 8, 9, 87]

s = np.sign(np.diff(lst))
# array([-1, -1, -1, -1, -1,  1,  1,  1,  1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()
# [-1, 1]

### second example

lst
# [8, 6, 4, 1, -2, -6, 5, -8, 9, 10]

s = np.sign(np.diff(lst))
# array([-1, -1, -1, -1, -1,  1, -1,  1,  1])

s[np.r_[True, s[:-1]!=s[1:]]].tolist()
# [-1, 1, -1, 1]
Answered By: mozway
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.