I have the following pandas data frame:
| user | day | value | value_cumulative |
|---|---|---|---|
| Allen | 2021-01-01 | 1 | 1 |
| Allen | 2021-02-01 | 2 | 3 |
| Allen | 2021-03-01 | 3 | 6 |
| Allen | 2021-04-01 | 4 | 10 |
| Karen | 2021-01-01 | 5 | 5 |
| Karen | 2021-02-01 | 6 | 11 |
| Karen | 2021-03-01 | 7 | 18 |
| Karen | 2021-04-01 | 8 | 26 |
Based on the above, I would like to add two columns that calculate decay in two different ways.
Version 1
This one is fairly straight forward. I simply want to take the current value plus the past values multiplied by the decay factor of 0.1.
| user | day | value | value_cumulative | decay_v1 | formula |
|---|---|---|---|---|---|
| Allen | 2021-01-01 | 1 | 1 | 1.000 | = 1 |
| Allen | 2021-02-01 | 2 | 3 | 2.100 | = 2 + 0.1 * 1 |
| Allen | 2021-03-01 | 3 | 6 | 3.210 | = 3 + 0.1 * 2.1 |
| Allen | 2021-04-01 | 4 | 10 | 4.321 | = 4 + 0.1 * 3.21 |
| Karen | 2021-01-01 | 5 | 5 | 5.000 | = 5 |
| Karen | 2021-02-01 | 6 | 11 | 6.500 | = 6 + 0.1 * 5 |
| Karen | 2021-03-01 | 7 | 18 | 7.650 | = 7 + 0.1 * 6.5 |
| Karen | 2021-04-01 | 8 | 26 | 8.765 | = 8 + 0.1 * 7.65 |
Version 2
This one is a bit more complicated. I'm using the following formula:
decay_v2 = 1 - exp(-x*value_cumulative)
where x is defined as follows:
x = -log(1-sat)/center
where I have chosen sat = 0.05 and center as the value_cumulative from 2021-03-01.
In the formula column below, the x is therefore:
Allen: -log(1-0.05)/6 = 0.0085489
Karen: -log(1-0.05)/18 = 0.0028496
| user | day | value | value_cumulative | decay_v2 | formula |
|---|---|---|---|---|---|
| Allen | 2021-01-01 | 1 | 1 | 0.009 | = 1-exp(-x*1) |
| Allen | 2021-02-01 | 2 | 3 | 0.025 | = 1-exp(-x*3) |
| Allen | 2021-03-01 | 3 | 6 | 0.050 | = 1-exp(-x*6) |
| Allen | 2021-04-01 | 4 | 10 | 0.082 | = 1-exp(-x*10) |
| Karen | 2021-01-01 | 5 | 5 | 0.014 | = 1-exp(-x*5) |
| Karen | 2021-02-01 | 6 | 11 | 0.031 | = 1-exp(-x*11) |
| Karen | 2021-03-01 | 7 | 18 | 0.050 | = 1-exp(-x*18) |
| Karen | 2021-04-01 | 8 | 26 | 0.071 | = 1-exp(-x*26 ) |
I have the feeling that it must be possible to somehow implement this using the ewm function (https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.ewm.html) but am unable to get it to work. Any ideas on how this could work?