I was hoping to run a script that will iterate through all fields in an attribute table, SUM each field and produce the result in a table.

The script below will essentially do what I want with one field but is there a way for it to iterate through all fields?

import arcpy

from arcpy import env  

env.workspace = "C:/data/Habitat_Analysis.gdb"  

arcpy.Statistics_analysis("FIELD_NAME", "C:/output/output.gdb/TABLE_OUTPUT", [["SUM"]])

(the above sample was sourced here: http://resources.arcgis.com/en/help/main/10.1/index.html#//00080000001z000000)


Doesn't the third example script in the link you mentioned do exactly what you want in a single table?

# Import system modules
import arcpy

# Set environment settings
arcpy.env.workspace = r"C:/data/Habitat_Analysis.gdb"

# Set local variables
intable = "FIELD_NAME"
outtable = "C:/output/output.gdb/TABLE_OUTPUT"
# casefield = "Name" Not used
stats = []

# Loop through all fields in the Input Table
for field in arcpy.ListFields(intable):
    # Just find the fields that have a numeric type
    if field.type in ("Double", "Integer", "Single", "SmallInteger"):
        # Add the field name and Sum statistic type
        #    to the list of fields to summarize
        stats.append([field.name, "Sum"])
# Correct formatting of stats [["Field1", "Sum"], ["Field2", "Sum"], ...]

# Run the Summary Statistics tool with the stats list
arcpy.Statistics_analysis(intable, outtable, stats)
| improve this answer | |
  • That's exactly how I would do it except inTable and outTable would be arguments to make that more flexible... and I'd also skip the OIDFieldName resources.arcgis.com/en/help/main/10.1/index.html#//… as the sum of that is (likely) of no value – Michael Stimson Nov 24 '14 at 22:53
  • The OID field is type OID, not Double, Integer, Single, or SmallInteger, so it's sum won't be in the output. See the type property under the arcpy field class. resources.arcgis.com/en/help/main/10.1/index.html#//… – Richard Fairhurst Nov 24 '14 at 23:24
  • 1
    Sometimes it is, sometimes it isn't, just to be sure I exclude it specifically. In reality it's just a number (INT) that's auto-managed by the database, guaranteed to be unique but not guaranteed to be the same feature every time (shapefile FID's change in an edit session). – Michael Stimson Nov 24 '14 at 23:45
  • In the case of the code above the listFields for loop with the field.type conditional statement as written will never include the OID field in the output, whether it is a shapefile, dbase table, geodatabase, etc. You would have to demonstrate a situation where that loop includes an actual OID field sum. – Richard Fairhurst Nov 25 '14 at 0:33
  • 2
    Got it. I can see why switching to different script/program languages would lead to a better safe than sorry approach. I just wanted it to be clear that for arcpy using the field type in this way is reliable for excluding the OID. – Richard Fairhurst Nov 25 '14 at 0:48

I would use a SearchCursor wrapped in a generator to get the summed fields. This is the full workflow:

  1. List all of the fields
  2. Create a function with a SearchCursor wrapped in a generator
  3. Loop through the fields
  4. Limit the fields to only those that are necessary with logic and implement the function

import arcpy, os

fc = r'C:\Users\OWNER\Documents\ArcGIS\Default.gdb\utm15\mypolys'

fields = arcpy.ListFields(fc)

def sumFields(x, y):
    field = sum([row[0] for row in arcpy.da.SearchCursor(x, y)])
    print "The sum of Field: %s = %s" % (y, field)

for f in fields:
    if f.type != "OID" and f.type != "Geometry":
        sumFields(fc, f.name)

enter image description here

enter image description here

| improve this answer | |
  • How does this code respond to a text or date field? – Richard Fairhurst Nov 25 '14 at 0:28
  • 1
    @RichardFairhurst You are correct that date and text fields should also be controlled for. Borrowing from your script, something along the lines of the following will work: if f.type not in ("OID", "Geometry", "Date", "Text"): – Aaron Nov 25 '14 at 3:45

Before you can complete your script I think you should write a short test script that simply takes a feature class and prints out the name of each field using ListFields.

From there modify your script so that only the names of numeric fields are printed - because you want to SUM them.

The final step is to incorporate a for loop to iterate your Summary Statistics.

| improve this answer | |
  • Beat me by 6 minutes... – Fezter Nov 24 '14 at 22:33
  • @Fezter but your answer is more comprehensive – PolyGeo Nov 24 '14 at 22:35
  • Many thanks for your reply. Your answer appears essentially the same as Fezter but I expanded on his somewhat more. – MapGeo Nov 24 '14 at 22:41

Have a look at the ListFields function. Note, you'll want to limit your results to numeric only fields, otherwise, you might get an error. So, you may want to use something like the following:

int_fields = arcpy.ListFields("C:/data/Habitat_Analysis.gdb", , "Integer")

to get a list of all integer fields.


small_int_fields = arcpy.ListFields("C:/data/Habitat_Analysis.gdb", , "SmallInteger")

to get a list of all small integer fields. Repeat again for doubles.

double_fields = arcpy.ListFields("C:/data/Habitat_Analysis.gdb", , "Double")

Finally, you can merge the lists together:

fields = int_fields + small_int_fields + double_fields

Then, you can iterate through all fields with a for loop.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.