title: Pandas: vectorization of Conditional Cumulative Sum
body: <p>I'm trying to vectorize a for loop in pandas to improve performance. I have a dataset comprising of users, products, the date of each service as well as the number of days supplied. Given the following subset of data:</p>
  
  <pre><code>testdf = pd.DataFrame(data={"USERID": ["A"] * 6,
                              "PRODUCTID": [1] * 6,
                              "SERVICEDATE": [datetime(2016, 1, 1), datetime(
                                  2016, 2, 5),
                               datetime(2016, 2, 28), datetime(2016, 3, 25),
                               datetime(2016, 4, 30), datetime(2016, 5, 30)],
                              "DAYSSUPPLY": [30] * 6})
  
  testdf=testdf.set_index(["USERID", "PRODUCTID"])
  testdf["datediff"] = testdf["SERVICEDATE"].diff()
  testdf.loc[testdf["datediff"].notnull(), "datediff"] = testdf.loc[
      testdf["datediff"].notnull(), "datediff"].apply(lambda x: x.days)
  testdf["datediff"] = testdf["datediff"].fillna(0)
  testdf["datediff"] = pd.to_numeric(testdf["datediff"])
  testdf["over_under"] = testdf["DAYSSUPPLY"].shift() - testdf["datediff"]
  </code></pre>
  
  <p>I would like to get the following result:</p>
  
  <pre><code>                  DAYSSUPPLY SERVICEDATE  datediff  over_under  desired
  USERID PRODUCTID                                                       
  A      1                  30  2016-01-01         0         NaN        0
         1                  30  2016-02-05        35        -5.0        0
         1                  30  2016-02-28        23         7.0        7
         1                  30  2016-03-25        26         4.0       11
         1                  30  2016-04-30        36        -6.0        5
         1                  30  2016-05-30        30         0.0        5
  </code></pre>
  
  <p>Essentially, I want my desired column to be the running sum of over_under, but to only sum the negative values if the value of desired on the previous line is > 0. desired should never get below 0. A quick and dirty loop over a [user, product] group looks something like this:</p>
  
  <pre><code>running_total = 0
  desired_loop = []
  for row in testdf.itertuples():
      over_under=row[4]
      # skip first row
      if pd.isnull(over_under):
          desired_loop.append(0)
          continue
      running_total += over_under
      running_total = max(running_total, 0)
      desired_loop.append(running_total)
  testdf["desired_loop"] = desired_loop
  
                    desired_loop
  USERID PRODUCTID              
  A      1                   0.0
         1                   0.0
         1                   7.0
         1                  11.0
         1                   5.0
         1                   5.0
  </code></pre>
  
  <p>I'm still new to vectorization and pandas and general. I've been able to vectorize every other calculation in this df, but this special case of a cumulative sum I just can't figure out how to go about it.</p>
  
  <p>Thanks!</p>