3

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)

0

4 Answers 4

3

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)
6
  • 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 Nov 24, 2014 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#//… Nov 24, 2014 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). Nov 24, 2014 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. Nov 25, 2014 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. Nov 25, 2014 at 0:48
2

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

2
  • How does this code respond to a text or date field? Nov 25, 2014 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, 2014 at 3:45
1

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.

3
  • Beat me by 6 minutes...
    – Fezter
    Nov 24, 2014 at 22:33
  • @Fezter but your answer is more comprehensive
    – PolyGeo
    Nov 24, 2014 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, 2014 at 22:41
1

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.

then

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.

1

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