'Calculate week/month-to-date change in Pandas (with grouped data)
I have panel data of stock tickers over time and the price of the stock each day.
I have seen solutions using pandas shift (code attempts to implement below) to calculate the change over a period (assuming a fixed number of days) but I need to calculate the change month-to-date, year-to-date, versus the last Friday (i.e week-to-date) etc. (I.e. the calculation is not over a fixed number of periods).
Code attempts:
df['Price_chg'] = df.groupby('Ticker')['Price'].apply(pd.Series.diff)
df['Price_chg'] = df.groupby('Ticker')['Price'].apply(lambda x: x - x.shift())
Example data:
| Ticker | Date | Price |
|---|---|---|
| AAUK | 2022-02-28 | 100 |
| AAUK | 2022-03-01 | 105 |
| AAUK | 2022-03-02 | 107 |
| AAUK | 2022-03-03 | 110 |
| AAUK | 2022-03-04 | 105 |
| AAUK | 2022-03-07 | 112 |
| AAUK | 2022-03-08 | 120 |
| AAUK | 2022-03-09 | 117 |
| AAUK | 2022-03-10 | 112 |
| AAUK | 2022-03-11 | 125 |
| ABX | 2022-02-28 | 100 |
| ABX | 2022-03-01 | 100 |
| ABX | 2022-03-02 | 110 |
| ABX | 2022-03-03 | 115 |
| ABX | 2022-03-04 | 117 |
| ABX | 2022-03-07 | 120 |
| ABX | 2022-03-08 | 122 |
| ABX | 2022-03-09 | 125 |
| ABX | 2022-03-10 | 127 |
| ABX | 2022-03-11 | 130 |
Desired output:
| Ticker | Date | Price | WTD | MTD |
|---|---|---|---|---|
| AAUK | 2022-02-28 | 100 | N/A | N/A |
| AAUK | 2022-03-01 | 105 | 5 | 5 |
| AAUK | 2022-03-02 | 107 | 7 | 7 |
| AAUK | 2022-03-03 | 110 | 10 | 10 |
| AAUK | 2022-03-04 | 105 | 5 | 5 |
| AAUK | 2022-03-07 | 112 | 7 | 12 |
| AAUK | 2022-03-08 | 120 | 15 | 20 |
| AAUK | 2022-03-09 | 117 | 12 | 17 |
| AAUK | 2022-03-10 | 112 | 7 | 12 |
| AAUK | 2022-03-11 | 125 | 20 | 25 |
| ABX | 2022-02-28 | 100 | N/A | N/A |
| ABX | 2022-03-01 | 100 | 0 | 0 |
| ABX | 2022-03-02 | 110 | 10 | 10 |
| ABX | 2022-03-03 | 115 | 15 | 15 |
| ABX | 2022-03-04 | 117 | 17 | 17 |
| ABX | 2022-03-07 | 120 | 3 | 20 |
| ABX | 2022-03-08 | 122 | 5 | 22 |
| ABX | 2022-03-09 | 125 | 8 | 25 |
| ABX | 2022-03-10 | 127 | 10 | 27 |
| ABX | 2022-03-11 | 130 | 13 | 30 |
Thanks
Solution 1:[1]
Have figured a solution by first extracting the week/month/quarter etc.
df['WEEK'] = pd.to_datetime(df['Date']).dt.to_period('W')
Then apply a broader grouping when applying the lambda function:
df['1WEEK_Price_chg'] = df.groupby(['Ticker', 'WEEK'])['Price'].apply(lambda x: x - x.shift())
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | malligator |
