1

I have perused GIS stack exchange to find an answer, but haven't quite found what I am looking for.

Question: How can I update all the fields in a feature class based upon field values from another feature class?

Here is my original feature class, (image on left) with 896 records of which I only need to update 11 records from the old feature class with the 11 records shown in the new UpdatedTAZnumbers feature class (image on right).

enter image description here

The new feature class which has the correct updated values has the exact same fields just with different values in them. There are over 100 fields thus joining the layers and using field calculator would take forever.

Therefore, I am thinking a script and in this case perhaps an updatecursor would be the best route to take.

I am fairly new to python and am struggling with something that seems so simple. My script below currently does not work and I know it starts with the line in the update cursor

 *while row:
 row.setValue(oldfc, row.getValue(newfc))*

I am using ArcGIS 10.3.1 and Python 2.7.

    import arcpy
    from arcpy import env

    from datetime import datetime
    startTime = datetime.now()

    arcpy.env.workspace = r"workspace.gdb"


    oldfc = r"workspace.gdb\TAZfromTransCAD...."

    newfc = r"workspace.gdb\UpdatedTAZnumbers"


    ##
    ##oldfields = [u'OBJECTID', u'Shape', u'ID', u'AREA', u'AREA1', u'TAZ', u'ACRES', u'HH2005', u'HH2010', u'HH2015', u'HH2020', u'HH2025', u'HH2030', u'HH2035', u'LOWINCHH05', u'LOWINCHH10', u'LOWINCHH15', u'LOWINCHH20', u'LOWINCHH25', u'LOWINCHH30', u'LOWINCHH35', u'MEDINCHH05', u'MEDINCHH10', u'MEDINCHH15', u'MEDINCHH20', u'MEDINCHH25', u'MEDINCHH30', u'MEDINCHH35', u'HIINCHH05', u'HIINCHH10', u'HIINCHH15', u'HIINCHH20', u'HIINCHH25', u'HIINCHH30', u'HIINCHH35', u'HHPOP2005', u'HHPOP2010', u'HHPOP2015', u'HHPOP2020', u'HHPOP2025', u'HHPOP2030', u'HHPOP2035', u'GQPOP2005', u'GQPOP2010', u'GQPOP2015', u'GQPOP2020', u'GQPOP2025', u'GQPOP2030', u'GQPOP2035', u'HHOF1_2005', u'HHOF1_2010', u'HHOF1_2015', u'HHOF1_2020', u'HHOF1_2025', u'HHOF1_2030', u'HHOF1_2035', u'HHOF2_2005', u'HHOF2_2010', u'HHOF2_2015', u'HHOF2_2020', u'HHOF2_2025', u'HHOF2_2030', u'HHOF2_2035', u'HHOF3_2005', u'HHOF3_2010', u'HHOF3_2015', u'HHOF3_2020', u'HHOF3_2025', u'HHOF3_2030', u'HHOF3_2035', u'HHOF4_2005', u'HHOF4_2010', u'HHOF4_2015', u'HHOF4_2020', u'HHOF4_2025', u'HHOF4_2030', u'HHOF4_2035', u'HHOF5_2005', u'HHOF5_2010', u'HHOF5_2015', u'HHOF5_2020', u'HHOF5_2025', u'HHOF5_2030', u'HHOF5_2035', u'HHOF6_2005', u'HHOF6_2010', u'HHOF6_2015', u'HHOF6_2020', u'HHOF6_2025', u'HHOF6_2030', u'HHOF6_2035', u'HHOF7_2005', u'HHOF7_2010', u'HHOF7_2015', u'HHOF7_2020', u'HHOF7_2025', u'HHOF7_2030', u'HHOF7_2035', u'POP019_05', u'POP019_10', u'POP019_15', u'POP019_20', u'POP019_25', u'POP019_30', u'POP019_35', u'POP2054_05', u'POP2054_10', u'POP2054_15', u'POP2054_20', u'POP2054_25', u'POP2054_30', u'POP2054_35', u'POP55_05', u'POP55_10', u'POP55_15', u'POP55_20', u'POP55_25', u'POP55_30', u'POP55_35', u'ELEM2005', u'ELEM2010', u'ELEM2015', u'ELEM2020', u'ELEM2025', u'ELEM2030', u'ELEM2035', u'HISCHL2005', u'HISCHL2010', u'HISCHL2015', u'HISCHL2020', u'HISCHL2025', u'HISCHL2030', u'HISCHL2035', u'COLLEGE05', u'COLLEGE10', u'COLLEGE15', u'COLLEGE20', u'COLLEGE25', u'COLLEGE30', u'COLLEGE35', u'AMC2005', u'AMC2010', u'AMC2015', u'AMC2020', u'AMC2025', u'AMC2030', u'AMC2035', u'MTCUW2005', u'MTCUW2010', u'MTCUW2015', u'MTCUW2020', u'MTCUW2025', u'MTCUW2030', u'MTCUW2035', u'RETAIL2005', u'RETAIL2010', u'RETAIL2015', u'RETAIL2020', u'RETAIL2025', u'RETAIL2030', u'RETAIL2035', u'SVCOFC2005', u'SVCOFC2010', u'SVCOFC2015', u'SVCOFC2020', u'SVCOFC2025', u'SVCOFC2030', u'SVCOFC2035', u'OTHER2005', u'OTHER2010', u'OTHER2015', u'OTHER2020', u'OTHER2025', u'OTHER2030', u'OTHER2035', u'GAMING2005', u'GAMING2010', u'GAMING2015', u'GAMING2020', u'GAMING2025', u'GAMING2030', u'GAMING2035', u'HOTELRM05', u'HOTELRM10', u'HOTELRM15', u'HOTELRM20', u'HOTELRM25', u'HOTELRM30', u'HOTELRM35', u'PARKING05', u'PARKING10', u'PARKING15', u'PARKING20', u'PARKING25', u'PARKING30', u'PARKING35', u'JURISDICT', u'JURISDNUM', u'REGCTR_TOD', u'RC_TOD_NUM', u'DISTRICT57', u'SHAPE_LENG', u'CBD', u'DISTRICT20', u'DISTNAME20', u'SHAPE@']
    ##newfields = [u'OBJECTID', u'Shape', u'ID', u'AREA',u'AREA1', u'TAZ', u'ACRES', u'HH2005', u'HH2010', u'HH2015', u'HH2020', u'HH2025', u'HH2030', u'HH2035', u'LOWINCHH05', u'LOWINCHH10', u'LOWINCHH15', u'LOWINCHH20', u'LOWINCHH25', u'LOWINCHH30', u'LOWINCHH35', u'MEDINCHH05', u'MEDINCHH10', u'MEDINCHH15', u'MEDINCHH20', u'MEDINCHH25', u'MEDINCHH30', u'MEDINCHH35', u'HIINCHH05', u'HIINCHH10', u'HIINCHH15', u'HIINCHH20', u'HIINCHH25', u'HIINCHH30', u'HIINCHH35', u'HHPOP2005', u'HHPOP2010', u'HHPOP2015', u'HHPOP2020', u'HHPOP2025', u'HHPOP2030', u'HHPOP2035', u'GQPOP2005', u'GQPOP2010', u'GQPOP2015', u'GQPOP2020', u'GQPOP2025', u'GQPOP2030', u'GQPOP2035', u'HHOF1_2005', u'HHOF1_2010', u'HHOF1_2015', u'HHOF1_2020', u'HHOF1_2025', u'HHOF1_2030', u'HHOF1_2035', u'HHOF2_2005', u'HHOF2_2010', u'HHOF2_2015', u'HHOF2_2020', u'HHOF2_2025', u'HHOF2_2030', u'HHOF2_2035', u'HHOF3_2005', u'HHOF3_2010', u'HHOF3_2015', u'HHOF3_2020', u'HHOF3_2025', u'HHOF3_2030', u'HHOF3_2035', u'HHOF4_2005', u'HHOF4_2010', u'HHOF4_2015', u'HHOF4_2020', u'HHOF4_2025', u'HHOF4_2030', u'HHOF4_2035', u'HHOF5_2005', u'HHOF5_2010', u'HHOF5_2015', u'HHOF5_2020', u'HHOF5_2025', u'HHOF5_2030', u'HHOF5_2035', u'HHOF6_2005', u'HHOF6_2010', u'HHOF6_2015', u'HHOF6_2020', u'HHOF6_2025', u'HHOF6_2030', u'HHOF6_2035', u'HHOF7_2005', u'HHOF7_2010', u'HHOF7_2015', u'HHOF7_2020', u'HHOF7_2025', u'HHOF7_2030', u'HHOF7_2035', u'POP019_05', u'POP019_10', u'POP019_15', u'POP019_20', u'POP019_25', u'POP019_30', u'POP019_35', u'POP2054_05', u'POP2054_10', u'POP2054_15', u'POP2054_20', u'POP2054_25', u'POP2054_30', u'POP2054_35', u'POP55_05', u'POP55_10', u'POP55_15', u'POP55_20', u'POP55_25', u'POP55_30', u'POP55_35', u'ELEM2005', u'ELEM2010', u'ELEM2015', u'ELEM2020', u'ELEM2025', u'ELEM2030', u'ELEM2035', u'HISCHL2005', u'HISCHL2010', u'HISCHL2015', u'HISCHL2020', u'HISCHL2025', u'HISCHL2030', u'HISCHL2035', u'COLLEGE05', u'COLLEGE10', u'COLLEGE15', u'COLLEGE20', u'COLLEGE25', u'COLLEGE30', u'COLLEGE35', u'AMC2005', u'AMC2010', u'AMC2015', u'AMC2020', u'AMC2025', u'AMC2030', u'AMC2035', u'MTCUW2005', u'MTCUW2010', u'MTCUW2015', u'MTCUW2020', u'MTCUW2025', u'MTCUW2030', u'MTCUW2035', u'RETAIL2005', u'RETAIL2010', u'RETAIL2015', u'RETAIL2020', u'RETAIL2025', u'RETAIL2030', u'RETAIL2035', u'SVCOFC2005', u'SVCOFC2010', u'SVCOFC2015', u'SVCOFC2020', u'SVCOFC2025', u'SVCOFC2030', u'SVCOFC2035', u'OTHER2005', u'OTHER2010', u'OTHER2015', u'OTHER2020', u'OTHER2025', u'OTHER2030', u'OTHER2035', u'GAMING2005', u'GAMING2010', u'GAMING2015', u'GAMING2020', u'GAMING2025', u'GAMING2030', u'GAMING2035', u'HOTELRM05', u'HOTELRM10', u'HOTELRM15', u'HOTELRM20', u'HOTELRM25', u'HOTELRM30', u'HOTELRM35', u'PARKING05', u'PARKING10', u'PARKING15', u'PARKING20', u'PARKING25', u'PARKING30', u'PARKING35', u'JURISDICT', u'JURISDNUM', u'REGCTR_TOD', u'RC_TOD_NUM', u'DISTRICT57', u'SHAPE_LENG', u'CBD', u'DISTRICT20', u'DISTNAME20', u'SHAPE@']

    cursor = arcpy.UpdateCursor(fc)
    row =cursor.next()

    while row:
        row.setValue(oldfc, row.getValue(newfc))
        cursor.updateRow(row)
        row = cursor.next()


    print datetime.now() - startTime
  • 1
    Could you please provide an example of the input data and the intended final output? A simplified example would be helpful. – Aaron Jan 23 '16 at 0:27
  • 1
    What field would you use to join the two feature classes together? Are you replacing the shapes as well as the attributes? If so, since they have the same schema, delete the original set of features and use the Append tool to insert the new set of features. If the features overlap, for only 11 features I would use the Attribute Transfer tool to match fields and then manually replace each feature. To automate, read the new features into a dictionary from a search cursor, then use an update cursor to update old features from the dictionary. But its not worth it for less than 30 features imho – Richard Fairhurst Jan 23 '16 at 1:30
2

To do this with ArcPy cursors I think you will need to use both a Search Cursor to read one table and an Update Cursor to write to the other.

Since you are using a version that is 10.1 or later I recommend using arcpy.da cursors rather than the old style because they are about 10 times as fast.

You would use a run through arcpy.da.SearchCursor() to load a Python dictionary with your IDs as the keys, and your values being a list of the field values.

Then use a run through arcpy.da.UpdateCursor() to read each list of field values and extract them into their correct fields.

However, if you did not have many fields to update and have a unique identifier that is common to both tables, then I think you will find this far easier to do in ArcMap (or ArcPy) by adding a join and then calculating fields in one table to be equal to joined fields from the other.

  • I can input a search cursor into the script. Would I create a list from that and then use that list to put into the update cursors? There is a unique identifier that is common to both tables, but adding a join and calculating over 100 fields would take a lot longer than executing an update cursor, unless I am mistaken? – Damien Jan 23 '16 at 0:06
  • 1
    Dictionary and ids are key words in @Polygeo answer – FelixIP Jan 23 '16 at 4:57
  • @Damien - Maybe my computer is much faster than yours, but a join and field calculator on ~100 rows is trivial for me. Just today, I tested the limits of this workflow. A join and calculate initiated from Table 1 (~9,000 records) to Table 2 (~20,000 records) only took about 3-5 minutes. However, another join between the same Table 1 and Table 3 (~44,000,000 records) took over an hour, and field calculator spun for over 30 min. – Priscilla Jan 29 '16 at 20:57
  • 2
    @Damien If you have not yet worked with Python dictionaries, I think they are an invaluable tool for ArcPy developers to know. – PolyGeo Jan 29 '16 at 23:32
  • 1
    The arcpy.da cursors (arcpy.da.SearchCursor, arcpy.da.UpdateCursor, and arcpy.da.InsertCursor) were introduced with ArcGIS 10.1 to provide significantly faster performance over the previously existing set of cursor functions (arcpy.SearchCursor, arcpy.UpdateCursor, and arcpy.InsertCursor). The original cursors are provided only for continuing backward compatibility. arcpy.da.UpdateCursor help – Abc1 Nov 29 '17 at 19:08
1

You can use Editor in ArcMap to just delete "old rows" and copy+paste the "new rows" to the original feature class or more recommended would be delete "old rows" with Editor and then use Append tool to add the "new rows" to the original feature class. Note that you need to have your new rows in the updated feature class be selected before running Append tool (otherwise you will add all rows in that feature class).

Note: this would work only if

  • the geometry in updated feature class is the one you want to use
  • you do not need to store ID number (because using delete and copy rows or Append would add the new rows to the end of the attribute table)
    -- if you wanted to solve this you could try to use Feature class to feature class first to store the rows "below" those you want to update (with the higher ID number than the deleted ones) in temporary feature class, then add the updated rows and finally add those stored in temporary feature class - this at least works in ArcMap 10.5.1 where with stopping and saving edits the FIDs are recalculated

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.