The code below is a quick script to calculate a list of specific cumulative production timeframes for any amount of data you may have. This is a common thing to calculate, but is extremely helpful when looking for more features in, say, a scenario where you are trying to build a machine learning algorithm to predict EURs or production at various times in a well's life.

In [1]:
import pandas as pd
import numpy as np

pd.set_option('display.max_columns', 500)
pd.set_option('display.float_format', lambda x: '%.6f' % x)
np.set_printoptions(suppress=True)
%matplotlib inline

In terms of the dataframe used here (ProdData), yours can be whatever dataframe in which you are storing your production data. Though, you will need some sort of "days on/producing" column for this script to work.

In [ ]:
ProdData['cum_days'] = ProdData['ActDaysOn'].groupby(ProdData['API']).cumsum()
ProdData['cum_oil'] = ProdData['Oil'].groupby(ProdData['API']).cumsum()
ProdData['cum_gas'] = ProdData['Gas'].groupby(ProdData['API']).cumsum()
ProdData['cum_boe'] = ProdData['cum_oil'] + ProdData['cum_gas']/6
ProdData['cum_water'] = ProdData['Water'].groupby(ProdData['API']).cumsum()
ProdData['cum_water_inj'] = ProdData['Water_Inj'].groupby(ProdData['API']).cumsum()
In [ ]:
ProdData['Cum_Oil_Answer'] = ''
ProdData['Cum_Water_Answer'] = ''
ProdData['Cum_Gas_Answer'] = ''
ProdData['Cum_Time_Frame_Days'] = ''

wellid = ProdData.API.unique()
dayslist = [30, 90, 180, 365, 545, 730]  #<-You can change these time frame values (days) to whatever number days you want.
dayscums = pd.DataFrame()

for i in wellid:
    for j in dayslist:
        tempdf = ProdData[ProdData.API == i]
        cumulativesht = tempdf.loc[(tempdf['cum_days'] >= j).idxmax(axis=1)]
        
        cumoilans = round((cumulativesht.cum_oil - ((cumulativesht.cum_days - j)*cumulativesht.daily_oil)),0)
        cumwaterans = round((cumulativesht.cum_water - ((cumulativesht.cum_days - j)*cumulativesht.daily_Water)),0)
        cumgasans = round((cumulativesht.cum_gas - ((cumulativesht.cum_days - j)*cumulativesht.daily_gas)),0)
        
        cumulativesht.Cum_Oil_Answer = cumoilans
        cumulativesht.Cum_Water_Answer = cumwaterans
        cumulativesht.Cum_Gas_Answer = cumgasans
        cumulativesht.Cum_Time_Frame_Days = j
        dayscums = pd.concat([dayscums, cumulativesht], axis = 1)

dayscums = dayscums.T
dayscums2 = dayscums[["API", "Cum_Gas_Answer", "Cum_Oil_Answer", "Cum_Water_Answer", "Cum_Time_Frame_Days"]]
dayscums2

I am going to go Martha Stewart on this one - I already have the dataframe of this one pickled and will show you that result.

In [6]:
dayscums2 = pd.read_pickle("D:/NewMexicoData/dayscums8519.pkl")

#I forgot to put units for others to read this properly, so this is one way to rename columns in Python.

dayscums2 = dayscums2.rename(columns={'Cum_Gas_Answer': 'Cum_Gas_Mcf', 'Cum_Water_Answer': 'Cum_Water_bbls', 
                                      'Cum_Oil_Answer': 'Cum_Oil_bbls', 'Cum_Time_Frame_Days': 'Cum_Time_days'})

dayscums2.head(15)
Out[6]:
API Cum_Gas_Mcf Cum_Oil_bbls Cum_Water_bbls Cum_Time_days
3117 30-015-37716 4158.000000 8564.000000 13571.000000 30
3119 30-015-37716 15091.000000 23384.000000 14023.000000 90
3122 30-015-37716 35899.000000 44474.000000 14023.000000 180
3129 30-015-37716 55098.000000 64972.000000 50330.000000 365
3134 30-015-37716 62157.000000 77682.000000 68836.000000 545
3141 30-015-37716 70937.000000 88550.000000 95235.000000 730
3207 30-015-38956 5595.000000 6906.000000 16800.000000 30
3209 30-015-38956 14297.000000 15714.000000 42005.000000 90
3212 30-015-38956 19470.000000 23177.000000 67841.000000 180
3218 30-015-38956 33508.000000 39206.000000 108323.000000 365
3224 30-015-38956 46485.000000 50933.000000 144005.000000 545
3230 30-015-38956 52937.000000 58823.000000 162158.000000 730
3291 30-015-40194 2439.000000 4334.000000 0.000000 30
3294 30-015-40194 20796.000000 13523.000000 0.000000 90
3297 30-015-40194 40066.000000 26421.000000 39555.000000 180

Don't like that format? This is the more horizontal version:

In [8]:
DayCum = dayscums2.pivot(index = "API", columns = "Cum_Time_days")
DayCum = DayCum.reset_index()
DayCum.head(15)
Out[8]:
API Cum_Gas_Mcf Cum_Oil_bbls Cum_Water_bbls
Cum_Time_days 30 90 180 365 545 730 30 90 180 365 545 730 30 90 180 365 545 730
0 30-015-00909 373726.000000 386618.000000 387044.000000 388010.000000 389374.000000 390215.000000 276863.000000 286625.000000 287341.000000 289469.000000 291769.000000 296192.000000 16165.000000 17197.000000 17390.000000 18783.000000 22244.000000 23019.000000
1 30-015-04343 8869.000000 9165.000000 9165.000000 9165.000000 9165.000000 9165.000000 149303.000000 154435.000000 154692.000000 155335.000000 155693.000000 156071.000000 134097.000000 138567.000000 138567.000000 138567.000000 141392.000000 143756.000000
2 30-015-10066 83745.000000 121852.000000 267195.000000 1404004.000000 2731721.000000 4073642.000000 176.000000 713.000000 1084.000000 3805.000000 8802.000000 16078.000000 153734.000000 158858.000000 158858.000000 1137795.000000 2194454.000000 3069091.000000
3 30-015-10222 7944.000000 31400.000000 67810.000000 89814.000000 107509.000000 120185.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 186.000000 234.000000 234.000000 234.000000 234.000000
4 30-015-10307 145341.000000 150304.000000 150478.000000 150917.000000 151294.000000 151762.000000 97717.000000 101207.000000 101548.000000 102373.000000 103059.000000 103734.000000 1013753.000000 1055628.000000 1067806.000000 1093759.000000 1116090.000000 1139143.000000
5 30-015-20590 13781.000000 56246.000000 104817.000000 173465.000000 216925.000000 254060.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1907.000000 3027.000000 3372.000000 3811.000000 4043.000000 4225.000000
6 30-015-20871 3316403.000000 3430495.000000 3436210.000000 3445349.000000 3457613.000000 3476657.000000 5540.000000 5725.000000 5725.000000 5725.000000 5725.000000 5725.000000 3184.000000 3290.000000 3290.000000 3290.000000 3290.000000 3290.000000
7 30-015-20940 910.000000 2213.000000 3296.000000 4036.000000 4528.000000 5505.000000 593.000000 1385.000000 2076.000000 2910.000000 3496.000000 5333.000000 480.000000 2427.000000 3647.000000 4545.000000 5242.000000 89533.000000
8 30-015-21066 0.000000 6252.000000 18083.000000 45493.000000 61784.000000 76017.000000 617.000000 10045.000000 25136.000000 51290.000000 67949.000000 82047.000000 20070.000000 42557.000000 64834.000000 99510.000000 122228.000000 141980.000000
9 30-015-22162 605622.000000 686956.000000 716826.000000 741102.000000 772332.000000 807709.000000 3647.000000 4152.000000 4272.000000 4319.000000 4414.000000 4566.000000 49690.000000 54318.000000 56122.000000 66919.000000 76559.000000 88131.000000
10 30-015-22627 6222132.000000 6434222.000000 6442109.000000 6456994.000000 6523059.000000 6595247.000000 65.000000 67.000000 67.000000 67.000000 67.000000 67.000000 599.000000 619.000000 619.000000 619.000000 619.000000 619.000000
11 30-015-24139 17843.000000 18705.000000 19123.000000 19998.000000 20998.000000 22023.000000 50730.000000 52946.000000 53770.000000 55423.000000 57216.000000 58696.000000 230934.000000 241759.000000 246529.000000 256028.000000 267812.000000 277201.000000
12 30-015-24206 342003.000000 369029.000000 373100.000000 391824.000000 401276.000000 411692.000000 0.000000 0.000000 1254.000000 4484.000000 6154.000000 7288.000000 4246.000000 4749.000000 4805.000000 16519.000000 25242.000000 38084.000000
13 30-015-25452 60730.000000 63217.000000 63976.000000 65687.000000 68062.000000 70145.000000 48985.000000 51124.000000 51628.000000 53043.000000 54963.000000 56940.000000 17214.000000 17903.000000 18093.000000 18622.000000 19175.000000 20445.000000
14 30-015-26907 32364.000000 36474.000000 40297.000000 47172.000000 53963.000000 58969.000000 17554.000000 20652.000000 23703.000000 27895.000000 29967.000000 31303.000000 92460.000000 107642.000000 123972.000000 156944.000000 189728.000000 217075.000000
In [ ]: