The Python Oracle

Calculate cumulative sum based on threshold and condition in another column numpy

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: A Thousand Exotic Places Looping v001

--

Chapters
00:00 Question
01:15 Accepted answer (Score 1)
02:26 Answer 2 (Score 1)
03:03 Thank you

--

Full question
https://stackoverflow.com/questions/6820...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #pandas #dataframe #numpy

#avk47



ACCEPTED ANSWER

Score 1


I hope I've understood your question right. This example will substract necessary value ("reset") when cumulative sum of sale is greater than 5 and IsSuccess==True:

df["SumSale"] = df["Sale"].cumsum()

# "reset" when SumSale>5 and IsSuccess==True
m = df["SumSale"].gt(5) & df["IsSuccess"].eq(True)
df.loc[m, "to_remove"] = df["SumSale"]
df["to_remove"] = df["to_remove"].ffill().shift().fillna(0)
df["SumSale"] -= df["to_remove"]

df = df.drop(columns="to_remove")

print(df)

Prints:

   Sale  IsSuccess  SumSale
0     1      False      1.0
1     2       True      3.0
2     3      False      6.0
3     2      False      8.0
4     4       True     12.0
5     3      False      3.0
6     5       True      8.0
7     5      False      5.0

EDIT:

def fn():
    sale, success = yield
    cum = sale
    while True:
        sale, success = yield cum
        if success and cum > 5:
            cum = sale
        else:
            cum += sale


s = fn()
next(s)
df["ss"] = df["IsSuccess"].shift()
df["SumSale"] = df.apply(lambda x: s.send((x["Sale"], x["ss"])), axis=1)
df = df.drop(columns="ss")
print(df)

Prints:

   Sale  IsSuccess  SumSaleExpected  SumSale
0    10      False               10       10
1     2       True               12       12
2     2      False                2        2
3     1      False                3        3
4     3       True                6        6
5     2      False                2        2
6     1       True                3        3
7     3      False                6        6
8     5      False               11       11
9     5      False               16       16