简体   繁体   中英

Detecting increasing and decreasing trend

I'm working on a project and trying to create a function that detects an increasing or decreasing trend by just giving it one element at a time since I don't have access to all the values at the beginning.

It would be like this:

First iteration:

def detect_trend(arr[0], k, r, q):
       return array_upward_trend, array_downward_trend

Second iteration:

def detect_trend(arr[1], k, r, q):
       return array_upward_trend, array_downward_trend

and so on.

The k is what defines a trend. Meaning that a trend is only formed if it has increased/decreased the last k elements. Although if a trend has started to form and after q elements we give the function the value arr[i] , if this value is either a duplicate or an element within a small range r from the previous element arr[i-1] given to the function, then it does not disrupt the creation of the trend.

For example, I have this array

arr=[72 92 42 130 131 412 412 512 345 301 257 101 101 65 72 87 89 80 76 76 75 72 73]

the output after len(arr) iterations would be

array_upward_trend=[[42 130 131 412 412 512],[65 72 87 89]]
array_downward_trend=[[512 345 301 257 101 101 65], [89 80 76 76 75 72 73]]

k=4 , q=3 and r=0.015 ( r in this case means a range of 1.5 %) for the example

I have not been able to make this work and once again starting from scratch. I would really appreciate any kind of help

Thanks

First of all, welcome to stackoverflow. Secondly, next time you might want to ask the question differently because this task has to many subtasks. Which means other people looking for help here will propably skip this post making answering it less worthwhile. Therefore I would suggest that you split you complex task into smaller ones.

The following code should work but is not very efficient yet but might give you an idea.

# =============================================================================
# complete function
# =============================================================================

def detect_trend(arr, number_new, k, r, q):

    # append new element to arr
    arr.append(number_new)

    # up trend
    arr_trends = []
    arr_add = []
    for i, number in enumerate(arr):
        if i != 0:
            previous_number = arr[i-1]

            if len(arr_add) >= q:
                if previous_number/number <= 1+r :
                    bool_logic = True
                else:
                    bool_logic = (previous_number <= number)
            else:
                bool_logic = (previous_number <= number)

            if bool_logic:
                if arr_add == []:
                    arr_add = arr_add + [previous_number]
                arr_add = arr_add + [number]
                if i == len(arr) - 1:
                    arr_trends.append(arr_add)
            else:
                arr_trends.append(arr_add)
                arr_add = []

    array_upward_trend = [trend for trend in arr_trends if len(trend)>=k]


    # down trend
    arr_trends = []
    arr_add = []
    for i, number in enumerate(arr):
        if i != 0:
            previous_number = arr[i-1]

            if len(arr_add) >= q:
                if previous_number/number >= 1-r :
                    bool_logic = True
                else:
                    bool_logic = (previous_number >= number)
            else:
                bool_logic = (previous_number >= number)

            if bool_logic:
                if arr_add == []:
                    arr_add = arr_add + [previous_number]
                arr_add = arr_add + [number]
                if i == len(arr) - 1:
                    arr_trends.append(arr_add)
            else:
                arr_trends.append(arr_add)
                arr_add = []

    array_downward_trend = [trend for trend in arr_trends if len(trend)>=k]

    return arr, array_upward_trend, array_downward_trend

arr = [72,92,42,130,131,412,412,512,345,301,257,101,101,65,72,87,89,80,76,76,75,72,73]
number_new = 74
q = 3
k = 4
r = 0.015

arr, array_upward_trend, array_downward_trend = detect_trend(arr, number_new, k, r, q)

How to get there? First you might want to split the complex problem into a list of simple problems. Then you start solving them one by one and combine them afterwards. Here is my approach:

First takle the propably most difficult one, because if you fail this the other tasks don't matter. Here it was trend detection in general.

# =============================================================================
# detect (up) trends
# =============================================================================

arr_trends = []
arr_add = []
for i, number in enumerate(arr):
    if i != 0:
        previous_number = arr[i-1]
        if (previous_number <= number):
            if arr_add == []:
                arr_add = arr_add + [previous_number]
            arr_add = arr_add + [number]
            if i == len(arr) - 1:
                arr_trends.append(arr_add)
        else:
            arr_trends.append(arr_add)
            arr_add = []

# =============================================================================
# consider q and r
# =============================================================================

arr_trends = []
arr_add = []
for i, number in enumerate(arr):
    if i != 0:
        previous_number = arr[i-1]

        if len(arr_add) >= q:
            if previous_number/number <= 1+r :
                bool_logic = True
            else:
                bool_logic = (previous_number <= number)
        else:
            bool_logic = (previous_number <= number)

        if bool_logic:
            if arr_add == []:
                arr_add = arr_add + [previous_number]
            arr_add = arr_add + [number]
            if i == len(arr) - 1:
                arr_trends.append(arr_add)
        else:
            arr_trends.append(arr_add)
            arr_add = []

# =============================================================================
# invert trend logic
# =============================================================================

arr_trends = []
arr_add = []
for i, number in enumerate(arr):
    if i != 0:
        previous_number = arr[i-1]

        if len(arr_add) >= q:
            if previous_number/number >= 1-r :
                bool_logic = True
            else:
                bool_logic = (previous_number >= number)
        else:
            bool_logic = (previous_number >= number)

        if bool_logic:
            if arr_add == []:
                arr_add = arr_add + [previous_number]
            arr_add = arr_add + [number]
            if i == len(arr) - 1:
                arr_trends.append(arr_add)
        else:
            arr_trends.append(arr_add)
            arr_add = []

# =============================================================================
# consider k
# =============================================================================

[trend for trend in arr_trends if len(trend)>=k]

# =============================================================================
# append new element to arr
# =============================================================================

arr.append(number_new)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM