1

I want to calculate cumulative field values using an case field from another column in ArcGIS 10.4.

For example, if I have an "ID" column and "Count" column inside my attribute table, I want to calculate cumulative values for each ID separately.

I have used this:

Calculating Cumulative Field Values in ArcMap enter image description here

I can do that if I select all rows with the same ID and run the field calculator, but that is a lot of manual work, so I want to use "ID" field as case field.

What is the best way to do that? Calculating Cumulative Field Values in ArcMap

enter image description here

user122678
  • 137
  • 1
  • 11
  • This is my attribute table: https://www.image-maps.com/m/private/0/ls0pba738cdjbqik8c8k060pru_cumulative.png – user122678 May 09 '20 at 12:53

2 Answers2

1

Although it is possible using for example dictionaries etc. (for example see: Numbering of objects based on several fields in ArcGIS with ArcPy) I would use pandas (which is included ArcMap >=10.4). When your data is in a pandas dataframe you can do any proccessing you can Think of.

import pandas as pd
import arcpy

fc = r"C:\GIS\data\testdata\ak_riks.shp"
fields = ['LANSKOD','area'] #field to group by, field with values to cumulative sum
field_to_calculate = 'cumsum'

df = pd.DataFrame.from_records(data=arcpy.da.SearchCursor(fc,fields), columns=fields) #Create a pandas dataframe using da.SearchCursor
df2 = df.groupby(fields[0])[fields[1]].cumsum() #https://stackoverflow.com/questions/32847800/how-can-i-use-cumsum-within-a-group-in-pandas
givecumsum = iter(df2.to_list()) #Iterator to return one value at a time
#givecumsum = iter(list(df2)) #If above line does not work

with arcpy.da.UpdateCursor(fc,field_to_calculate) as cursor:
    for row in cursor:
        row[0] = next(givecumsum)
        cursor.updateRow(row)

Screenshot from Pro but the code for ArcMap is the same: enter image description here

BERA
  • 72,339
  • 13
  • 72
  • 161
1

I save my field calculator expressions in the same folder. They are easily located by name and this is why I often prefer them over scripts, especially when execution time is not an issue.

So with slight modification of this solution, accumulation by group can be achieved by using:

d={}
def GroupOrder(groupID,toSum):
  N=d.get(groupID,0);N+=toSum
  d[groupID]=N
  return N
#--------------
GroupOrder(!to_node!, !Shape_Length!)
FelixIP
  • 22,922
  • 3
  • 29
  • 61