Finding sum of values in field

15189
18
10-11-2011 12:46 PM
StephenFricke
New Contributor III
I have a cities feature class with a field for the Population in the attribute table. I want to find the sum of all the values in the Population field which will give me the total population of all the cities. I think I might have to use the arcpy.CalculateField_management function but I am confused on the syntax I should be using, or maybe there is a different way I should be writing the script. Any help would be much appreciated!
Tags (2)
0 Kudos
18 Replies
RichardFairhurst
MVP Honored Contributor
You could use the Summarize tool without a case field and sum the population.  You could add a temporary field to both tables with a dummy value like 1 and join the result to your original layer on that field.  Then you can calculate over the resulting summed value to all of the records or get percentages.  Or else add the dummy field to your original layer first and use that as the Case field for the summary.

A cursor in python could also do the sum and write the result, but not the field calculator.
0 Kudos
StephenFricke
New Contributor III
Could you tell me what the syntax would be for finding the sum of a field with a cursor?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Hi Peter,

Here is an example on how to do this.  The below code will append all the rows from the population field to a list using a search cursor, then it will sum the list.

import arcpy
from arcpy import env
env.workspace = r"C:\temp\python\test.gdb"

fc = "Cities"

list = []

rows = arcpy.SearchCursor(fc)
for row in rows:
    pop = row.getValue("POPULATION")
    list.append(pop)

print sum(list) 
0 Kudos
StephenFricke
New Contributor III
Hey Jake, thanks!  That was a lot of help.  I am still getting an error when I run my script saying <type 'exceptions.TypeError'>: coercing to Unicode: need string or buffer, int found.  Could you please take a look at the script and let me know what the error might be?

inWorkspace = "C:/TEMP/Tooldata/Florida.gdb"
arcpy.env.workspace = inWorkspace
inPoly = "C:/TEMP/Tooldata/Florida.gdb/Counties"
inPoint = "C:/TEMP/Tooldata/Florida.gdb/Cities"
destField = "URBPOP"
msg = "Workspace is " + arcpy.env.workspace
arcpy.AddMessage(msg)
fcList = arcpy.ListFeatureClasses()
msg = "\nFeature classes in " + inWorkspace + ":"
arcpy.AddMessage(msg)
for anFC in fcList:
    msg = " - " + anFC
    arcpy.AddMessage(msg)
fldList = arcpy.ListFields(inPoly)
msg = "\nFields in " + inPoly + ":"
arcpy.AddMessage(msg)
for aFld in fldList:
    msg = " - " + aFld.name
    arcpy.AddMessage(msg)
fieldPresent = False
for aFld in fldList:
    if aFld.name == destField:
        fieldPresent = True
if not fieldPresent:
    arcpy.AddField_management(inPoly,destField,"DOUBLE")
    msg = "\nNew Field " + destField + " created in " + inPoly
    arcpy.AddMessage(msg)
arcpy.MakeFeatureLayer_management(inPoly,"allPolys")
arcpy.MakeFeatureLayer_management(inPoint,"allPoints")
polyRows = None
polyRow = None
polyRows = arcpy.UpdateCursor(inPoly)
msg = '\nUpdate cursor created for ' + inPoly + '. Records are:'
arcpy.AddMessage(msg)
for polyRow in polyRows:
    firstPart = '"NAME_1" ='
    lastPart = "'" + '' + "'"
    where_clause = firstPart + lastPart
    arcpy.MakeFeatureLayer_management(inPoly,"oneCounty",where_clause)
    arcpy.SelectLayerByLocation_management("allPoints", "WITHIN", "oneCounty")
    list= []
    fc = "allPoints"
    rows = arcpy.SearchCursor(fc)
    for row in rows:
        pop = row.getValue("POP_98")
        list.append(pop)
    msg = " - " + polyRow.NAME_1 + " - " + "Urban Population: " + sum(list)
    UrbanPop= sum(list)
    arcpy.AddMessage(msg)
    polyRow.URBPOP = int(UrbanPop)
    arcpy.Delete_management("oneCounty")

if polyRow:
    del polyRow
if polyRows:
    del polyRows
arcpy.Delete_management("allPolys")
arcpy.Delete_management("allPoints")



The first part of the script is not important, the last part where I am trying to sum the population of cities for each county is the part that I am struggling with.  Let me know if you see what I'm doing wrong.  Thanks!
0 Kudos
MathewCoyle
Frequent Contributor
This line is probably the problem.

msg = " - " + polyRow.NAME_1 + " - " + "Urban Population: " + sum(list)

You can't concatenate strings and ints. The blow line should fix it.
msg = " - " + polyRow.NAME_1 + " - " + "Urban Population: " + str(sum(list))


I didn't see anywhere else where that error is made, but you'd need to change it if you are putting together strings and numeric types anywhere else as well.
0 Kudos
JakeSkinner
Esri Esteemed Contributor
I believe you will also need to add another line for the update to occur. 

for polyRow in polyRows:
    firstPart = '"NAME_1" ='
    lastPart = "'" + '' + "'"
    where_clause = firstPart + lastPart
    arcpy.MakeFeatureLayer_management(inPoly,"oneCounty",where_clause)
    arcpy.SelectLayerByLocation_management("allPoints", "WITHIN", "oneCounty")
    list= []
    fc = "allPoints"
    rows = arcpy.SearchCursor(fc)
    for row in rows:
        pop = row.getValue("POP_98")
        list.append(pop)
    msg = " - " + polyRow.NAME_1 + " - " + "Urban Population: " + sum(list)
    UrbanPop= sum(list)
    arcpy.AddMessage(msg)
    polyRow.URBPOP = int(UrbanPop)
    polyRows.updateRow(polyRow)
    arcpy.Delete_management("oneCounty")
0 Kudos
DarrenWiens2
MVP Honored Contributor
Along different lines, you can do this in the field calculator.

expression:
func()


codeblock:
def func():
    sum = 0
    fc = "H:/GIS_Data/TEMP.gdb/points" # the path to your feature class

    rows = arcpy.SearchCursor(fc)

    for row in rows:
        sum = row.THEFIELDTOSUM + sum # enter the fieldname in this line
    
    return sum
0 Kudos
StephenFricke
New Contributor III
Hey thanks for the help everyone.  I am getting my script to run but when it runs the urban population for every county is being printed as 0.  Can anyone tell me why this would be with the way the script currently is?  I also tried the way dkwiens suggested and I am also getting zero for the Urban population in each county.

inWorkspace = "C:/TEMP/Tooldata/Florida.gdb"
arcpy.env.workspace = inWorkspace
inPoly = "C:/TEMP/Tooldata/Florida.gdb/Counties"
inPoint = "C:/TEMP/Tooldata/Florida.gdb/Cities"
destField = "URBPOP"

fieldPresent = False
for aFld in fldList:
    if aFld.name == destField:
        fieldPresent = True
if not fieldPresent:
    arcpy.AddField_management(inPoly,destField,"DOUBLE")
    msg = "\nNew Field " + destField + " created in " + inPoly
    arcpy.AddMessage(msg)
arcpy.MakeFeatureLayer_management(inPoly,"allPolys")
arcpy.MakeFeatureLayer_management(inPoint,"allPoints")
polyRows = None
polyRow = None
polyRows = arcpy.UpdateCursor(inPoly)
msg = '\nUpdate cursor created for ' + inPoly + '. Records are:'
arcpy.AddMessage(msg)
for polyRow in polyRows:
    firstPart = '"NAME_1" ='
    lastPart = "'" + '' + "'"
    where_clause = firstPart + lastPart
    arcpy.MakeFeatureLayer_management(inPoly,"oneCounty",where_clause)
    targetCities = arcpy.SelectLayerByLocation_management("allPoints", "WITHIN", "oneCounty")
    list= []
    rows = arcpy.SearchCursor(targetCities)
    for row in rows:
        pop = row.getValue("POP_98")
        list.append(pop)
    msg = " - " + polyRow.NAME_1 + " - " + "Urban Population: " + str(sum(list))
    arcpy.AddMessage(msg)
    UrbanPop= sum(list)
    polyRow.URBPOP = int(UrbanPop)
    polyRows.updateRow(polyRow)
    arcpy.Delete_management("oneCounty")

if polyRow:
    del polyRow
if polyRows:
    del polyRows
arcpy.Delete_management("allPolys")
arcpy.Delete_management("allPoints")
0 Kudos
JakeSkinner
Esri Esteemed Contributor
From the looks of your code I believe you are trying to select all cities within a county, sum the population of the cities and update a field in the counties feature class with this value.  You can easily do this by creating a spatial join.  You can right-click on the counties feature class in ArcMap's table of contents > Joins and Relates > Joins.  Specify to join attributes spatially and choose to sum the fields.

This will produce a new output feature class with the summed population (and summed outputs of all other numeric fields) of all cities within each county.  If you do not want a new feature class, and the other summed numeric fields, you can use python.  Here is the code that I was able to get to work:

import arcpy
from arcpy import env
env.workspace = r"C:\temp\python\test.gdb"
env.overwriteOutput = True

cities = "Cities"
counties = "Counties"

arcpy.MakeFeatureLayer_management(cities, "cities_feat")

list = []

# Get max OBJECTID for loop
rows = arcpy.SearchCursor(counties)
for row in rows:
    OID = row.getValue("OBJECTID")
    list.append(OID)

maxOID = list[-1]

del row, rows

x = 1
while x <= maxOID:
    list2 = []
    arcpy.MakeFeatureLayer_management(counties, "counties_feat", "OBJECTID = " + str(x))
    arcpy.SelectLayerByLocation_management("cities_feat", "WITHIN", "counties_feat")
    rows = arcpy.SearchCursor("cities_feat")
    for row in rows:
        pop = row.getValue("POPULATION")
        list2.append(pop)
    sumlist = sum(list2)
    rows2 = arcpy.UpdateCursor("counties_feat")
    for row2 in rows2:
        row2.URBPOP = sumlist
        rows2.updateRow(row2)
    x += 1

del row, rows, row2, rows2
0 Kudos