Problem:
What'd I like to do is step-by-step reduce a value in a Series
by a continuously decreasing base figure.
I'm not sure of the terminology for this - I did think I could do something with cumsum
and diff
but I think I'm leading myself on a wild goose chase there...
Starting code:
import pandas as pd
ALLOWANCE = 100
values = pd.Series([85, 10, 25, 30])
Desired output:
desired = pd.Series([0, 0, 20, 30])
Rationale:
Starting with a base of ALLOWANCE
- each value in the Series
is reduced by the amount remaining, as is the allowance itself, so the following steps occur:
85
so it becomes 0
, we now have 15
left as ALLOWANCE
10
and we still have 15
available, so this becomes 0
again and we have 5
left.25
- we only have 5
left, so this becomes 20
and now we have no further allowance.30
, and since there's no allowance, the value remains as 30
.To find the original value of an amount before the percentage increase/decrease: Write the amount as a percentage of the original value. Find 1% of the original value. The original value is 100%, so multiply by 100 to give the original value.
Following your initial idea of cumsum
and diff
, you could write:
>>> (values.cumsum() - ALLOWANCE).clip_lower(0).diff().fillna(0)
0 0
1 0
2 20
3 30
dtype: float64
This is the cumulative sum of values
minus the allowance. Negative values are clipped to zeros (since we don't care about numbers until we have overdrawn our allowance). From there, you can calculate the difference.
However, if the first value might be greater than the allowance, the following two-line variation is preferred:
s = (values.cumsum() - ALLOWANCE).clip_lower(0)
desired = s.diff().fillna(s)
This fills the first NaN
value with the "first value - allowance" value. So in the case where ALLOWANCE
is lowered to 75, it returns desired
as Series([10, 10, 25, 30])
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With