Frank Wang
Frank Wang

Reputation: 51

How to determine the trend of a numeric list in Python

Is there any easy way to find out what's the trend of the list?

For example:

Ideally, I want a Boolean result from these kinds of lists.

Actually, I'd like to know the trend of a collection of data. not linear increasing or exactly increasing one by one. In the real world, some data not always good, Perhaps there are one or two quarters of data not as good as it used to be(but not too bad, also not too much), but as long as Its trend is good, It is good.

Upvotes: 4

Views: 8313

Answers (3)

I just had the same issue, and created a version using only pandas for this problem, making the implementation of the moving_average function unnecessary.

def get_trend(array=[], reverse=False):
    array  = pd.Series(array).iloc[::-1].reset_index(drop=True) if reverse else pd.Series(array) #reverse Array if needed and convertes it to a pandas Series object
    trend  = pd.Series(array).rolling(len(array)-1).mean().dropna().reset_index(drop=True)             #calculate MA from array
    return -1 if trend[0] > trend[1] else 1 if trend[0] < trend[1] else 0

The function returns 1 for uptrends, -1 for downtrends and 0 if neither of those are given.

According to my measurements, using your arrays from above, this function takes about 0.002 seconds per call.

Upvotes: 0

Aaditya Ura
Aaditya Ura

Reputation: 12669

You can simply check , Will this work ?

def checker(list_):
    check={}
    temp = []
    for m, n in enumerate(list_):
        try:
            if list_[m] < list_[m + 1]:
                temp.append('Increasing')
            else:
                temp.append('Decreasing')
        except IndexError:
            pass
    check[temp.count('Increasing')] = 1
    check[temp.count('Decreasing')] = 0


    return check[max(check)]

test_Case 1:

print(checker([5.0, 6.0, 9.0, 4.0, 10.0]))

output:

1

test_Case 2

print(checker([6.0, 4.0, 5.0, 4.0, 3.0]))

output:

0

Upvotes: 0

jpp
jpp

Reputation: 164673

On the whole, Its elements are increasing.

I take this to mean you want to consider the change in moving average. Half the job is defining what you really want, so I advise you think carefully about this before starting to write logic.

I've combined a moving average solution by @Jaime with np.diff to suggest a possible way to infer what you want.

import numpy as np

def moving_average(a, n=3) :
    ret = np.cumsum(a, dtype=float)
    ret[n:] = ret[n:] - ret[:-n]
    return ret[n - 1:] / n

lst1 = [5.0, 6.0, 9.0, 4.0, 10.0]
lst2 = [6.0, 4.0, 5.0, 4.0, 3.0]

res1 = np.all(np.diff(moving_average(np.array(lst1), n=4))>0)
# True; i.e. "generally increasing"

res2 = np.all(np.diff(moving_average(np.array(lst2), n=4))>0)
# False, i.e. "generally not increasing"

Explanation

  • moving_average calculates the moving average across a window of 4 entries.
  • In each case you get an array of 2 numbers (for list of length 5).
  • np.diff then calculates the pairwise changes between these numbers.
  • np.all with test >0 determines if the changes are all positive or not all positive. An oversimplification driven by no clear requirement.

Upvotes: 11

Related Questions