0

I want to calculate the future continuous increase or decrease count for each element.

Assume I have a series:

l=[10, 9, 8, 9, 10, 9, 10, 11, 10, 12, 10]
s=pd.Series(l)

The expected output is:

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

Here is the explanation:

the first element is 10, the next is 9, the next is 8, so, it decrease 2 times, so the output is -2, for the third element is 8, it increase 2 times (the next is 9, 10), so output is 2.

The key point is continuous, once it has reverse data, it should be stop look forward.

How can I implement that? I think for loop is not good enough

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
xyhuang
  • 414
  • 3
  • 11
  • Something for you to start with `np.sign(-s.diff(-1).fillna(0))` – taras Dec 23 '20 at 09:08
  • @xyhuang : Does the answer helps? or you are still stuck? – Pygirl Dec 26 '20 at 08:24
  • @Pygirl thanks, i think your answer is good, but i want to know if there is some matrix method we can use, for loop maybe not the fastest – xyhuang Dec 29 '20 at 12:08
  • I have updated my answer also gave you pandas solution. This will help you : https://stackoverflow.com/questions/25119524/pandas-conditional-rolling-count – Pygirl Dec 29 '20 at 13:13

1 Answers1

1

1st get the sign of difference. Then find how many are consecutive same sign. If same then add the quantity. try:

import numpy as np
l=np.array([10, 9, 8, 9, 10, 9, 10, 11, 10, 12, 10])
sign = np.sign(np.diff(l))
count = {}
for i in range(len(sign)-1):
    count[i] = sign[i]
    for j in range(i+1, len(sign)):
        if sign[i]==sign[j]:
            count[i] += sign[j]
        else:
            break
count[i+1] = 0
res = count.values()

res:

dict_values([-2, -1, 2, 1, -1, 2, 1, -1, 1, 0])

Edit:

If you want to use pandas

df = pd.DataFrame(sign, columns=['col'])
df = df[::-1]
x = df.groupby((df['col'] != df['col'].shift(1)).cumsum()).cumsum()['col']
x.iloc[0]=0
x = x.values[::-1]

x:

array([-2, -1,  2,  1, -1,  2,  1, -1,  1,  0])

instead of :

(df['col'] != df['col'].shift(1)).cumsum()

you can use

df.col.diff().ne(0).cumsum()

Explanation

Pygirl
  • 12,969
  • 5
  • 30
  • 43