Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle pct_change with negative values

Tags:

python

pandas

I am calculating percentage change for a panel dataset, which has both positive and negative values. If both values of n and n+1 date are negative and values of n > n+1, for instance, n=-2, n+1=-4. The calculated percentage change is ((n+1)-n)/n=((-4)-(-2))/-2=1. As you can see the change should be a downtrend, which is expected to be negative but the result is the opposite. I normally set the denominators the absolute values ((n+1)-n)/abs(n) in other software to ensure the direction of the trend. Just wondering if I can do so in Python pandas pct_change to set up the denominator to be absolute values. Many thanks. I have solved the question based on the answer from Leo.

Here is a data example if one wants to play around.

import pandas as pd
df= {'id':[1,1,2,2,3,3],'values':[-2,-4,-2,2,1,5]}
df=pd.DataFrame(data=df)
df['pecdiff']=(df.groupby('id')['values'].apply(lambda x:x.diff()/x.abs().shift()
)).fillna(method=bfill)
like image 831
S Hendricks Avatar asked Dec 05 '25 04:12

S Hendricks


1 Answers

If I understood correctly, the line for expected change should solve your problem. For comparison, I put side by side pandas' method and what you need.

The following code:

import pandas as pd

df = pd.DataFrame([-2,-4,-2,2,1], columns = ['Values'])
df['pct_change'] = df['Values'].pct_change()

# This should help you out:
df['expected_change'] = df['Values'].diff() / df['Values'].abs().shift()
df

Gives this output. Note that the signs are different for lines 1 through 3

    Values  pct_change  expected_change
0       -2        NaN               NaN
1       -4        1.0              -1.0
2       -2       -0.5               0.5
3        2       -2.0               2.0
4        1       -0.5              -0.5
like image 96
leo.barddal Avatar answered Dec 06 '25 18:12

leo.barddal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!