I have a shapefile with 5,000 city points. I need to populate a new field, "cls_pop", based on each cities population, so that cities with a population > 2,000,000 will have "cls_pop" = 1, cites with a population > 1,800,000 and < 1,600,000 = 2 and so on and so on. I know there are a lot of different ways to accomplish this and I think I have really confused myself reading to much. I want to write this as a arcpy script so I can change out the variables and use it on different fields but I'm unsure of the best way to go about this. I wrote this but it just places "1" in each row of pop_class.

city_points = "C:\\Desktop\\citypoints.shp"

cursor = arcpy.SearchCursor(city_points,"", "", "population")

for row in cursor:
    if row.getValue(cursor) > 2000000:
        arcpy.CalculateField_management(city_points, "cls_pop", '"{0}"'.format(1), "PYTHON")

    if row.getValue(cursor) > 1800000 and row.getValue(field) < 2000000:
        arcpy.CalculateField_management(city_points, "cls_pop", '"{0}"'.format(2), "PYTHON")


Am I on the correct track or is there a better way for me to do this?

  • 1
    Shouldn't row.getValue(cursor) be row.getValue("pop_class") – Nathan W Aug 5 '13 at 23:30
  • No because I need to get the value from the cursor in order to populate cls_pop. So if cursor is > greater than 2000000 I want cls_pop to = 1 – user2284060 Aug 5 '13 at 23:36
  • 1
    cursor is a Cursor object which gives you a row which contains the data. I'm pretty sure you need to do row.population. getValue(field_name) takes a field name cursor is not a field ref help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… – Nathan W Aug 5 '13 at 23:41
  • If the classes have uniform widths, then perhaps the easiest and fastest solution is to compute cls_pop arithmetically. This can be done in one simple field calculation. Although the description in the question seems confused (it skips from the interval [2000000, Infinity] to [1600000, 1800000]) it likely is intended to equal max(1, 11 - int("population"/200000)), which assigns 1 to [2000000, infinity), 2 to [1800000, 2000000), 3 to [1600000, 1800000), and so on, down to 11 for [0, 200000). – whuber Aug 6 '13 at 15:08

This code is untested but I think will be much closer to what you want - key first thing is that you need to use an UpdateCursor.

The other thing that I have done is to use three ways to get and set the values of the current row in your cursor - in practice just choose one of them.

The first (on the if) is the simplest but "hardwires" the field names.
The second (on the elif) uses a slightly longer syntax but still "hardwires" the field names.
The last (on the else) lets you pass in a variable holding the field name.

city_points = "C:\\Desktop\\citypoints.shp"

cursor = arcpy.UpdateCursor(city_points)
classPopVar = "cls_pop"

for row in cursor:
    if row.population >= 2000000:
        row.cls_pop = 1
    elif row.getValue("population") >= 1800000 and row.getValue("population") < 2000000:
        row.setValue("cls_pop") = 2
        row.setValue(classPopVar) = 3
del row,cursor
  • Easy as that. On a side note: how does arcpy handle a column like cls pop when using the row. style? – Nathan W Aug 6 '13 at 0:01
  • Pretty sure that it would not like it. Personally I never try blanks in field names because this page says "Database management systems have different definitions of acceptable characters for object names. Most must begin with a letter and cannot contain spaces or back slashes." – PolyGeo Aug 6 '13 at 0:06
  • Thanks for the help! I'll be testing this out first thing in the morning when I get back to the office and let you know how it works. – user2284060 Aug 6 '13 at 0:46
  • I just got to my office and ran the code but there is a syntax error "There's an error in your program: *** can't assign to function call (line 15)" Line 15 in my code row.setValue("cls_pop") = 2 – user2284060 Aug 6 '13 at 13:09
  • I think this means that "C:\\Desktop\\citypoints.shp" does not have a numeric field called "cls_pop" so can you check the field name and type are as expected, please? – PolyGeo Aug 6 '13 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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