Thanks a lot for the tip. It worked for me. Easy and neat.
I think the way you have written the last part does not accumulated the values from the first key of the dictionary to the last. It only seems to add the current and prior year, not the current and all prior years. I think the last part needs a variable outside the loop to accumulate the summary values for each successive sorted year as shown below:
#Print some output cum = 0 for yearValue in sorted(summaryDict): cum += summaryDict[yearValue] print '{0} = {1} acres'.format(str(yearValue), str(cum))
This has the benefit of not needing to assume that each year key has a prior year value, which allows years to be skipped if the data did not have every year (and the first year should throw an error with Joshua's code as shown since there is no prior year key in the dictionary for the first year, but it still needs to print).
The code by Chris Snyder has all of the information already available in the summaryDict, you just need to add some logic to the final loop to grab the previous year in addition to the current year. Moving to a defaultdict instead of a regular dictionary allows the original code to be simplified some.
from collections import defaultdict myTable = r"C:\test.gdb\my_table" summaryDict = defaultdict(float) searchRows = arcpy.da.SearchCursor(myTable, ["YEAR","ACRES"]) for yearValue, acresValue in searchRows: summaryDict[yearValue] += acresValue #Print some output for yearValue in sorted(summaryDict): print str(yearValue) + " = " + str(summaryDict[yearValue] + summaryDict[yearValue - 1]) + " acres"
Great stuff thanks! I'm hoping to use this to create creaming curves for oil and gas exploration. What I have noticed is that it creates totals of a value per yer but I think the main aim was to create cumulative totals. As an example I used this code on my data:
2011 = 35.0 mmboe
2012 = 616.666667 mmboe
2013 = 389.166667 mmboe
2014 = 348.333333 mmboe
2015 = 107.5 mmboe
2016 = 433.333333 mmboe
Of which is correct as it creates totals for each year. Is it possible to create a cumulative total of this so each previous year is added to the total of the following year? I then want to plot cumulative curves using matplotlib.
myTable = r"C:\test.gdb\my_table" summaryDict = {} searchRows = arcpy.da.SearchCursor(myTable, ["YEAR","ACRES"]) for searchRow in searchRows: yearValue, acresValue = searchRow if yearValue in summaryDict: summaryDict[yearValue] = summaryDict[yearValue] + acresValue else: summaryDict[yearValue] = acresValue yearKeys = summaryDict.keys() yearKeys.sort() #sort the years in ascending order #Print some output for yearValue in yearKeys: print str(yearValue) + " = " + str(summaryDict[yearValue]) + " acres"
plt.figure() #...plotting code here plt.savefig(out) plt.close()
# import the module, arcpy... import arcpy # Set the current workspace environment variable. arcpy.env.workspace = r'C:\Documents and Settings\whitley-wayne\My Documents\ArcGIS\Default.gdb' # I set up a 'mock' table representing the summary output table, # called 'SummaryStatsOutput'. Set the table variable 'tbl' to that... tbl = 'SummaryStatsOutput' # Define another variable 'accumVal' to represent accumulated ACREAGE. # Initiate it to zero (0). accumVal = 0 # Establish the 'rows' cursor variable on tbl, which takes 5 parameters - # The 3 middle ones are 'blank'... # The last one is the sort parameter - sorting by YEAR... # (since my mock table was not in order). rows = arcpy.UpdateCursor(tbl, '', '', '', 'YEAR A') # looping on 'row' objects contained in the 'rows' cursor object... for row in rows: # Adding the current 'getValue' fetch from the ACREAGE field to accumVal. # (This is '0' for 1st record). accumVal = accumVal + row.getValue('ACREAGE') # Setting the ACREAGE field to the 'new' accumVal. # (a new field wasn't necessary) row.setValue('ACREAGE', accumVal) # Updating the row object within the cursor object # (committing the changes) rows.updateRow(row) # Outside the loop, delete the objects to remove lock reference on table del row, rows
Hello,I would like to use python to create a cumulative sum so that I end up with a table that looks like:1976 61978 21979 51980 13
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.