1

NOTE: If you look at the excel tables just above the comment section it will give a clearer picture of what I want to achieve in my code.

So the code below works in doing what I want it to do thus far, which is take a feature class (see first attribute table) and copy it a certain amount of times based upon the PHASE_COUNT field (see second attribute table for what output looks like).

What I am having trouble with is attempting to increment the MODEL_YEAR field with my code in my output feature class. This is where I need assistance. I am trying to increment the model_year field by +1 year for each duplicate record. For example, I have shown one of the repeated output records below that has a Phase_Count of 3 and is therefore repeated 3 times and has a TMRPA_ID of 4926 and MODEL_YEAR = 2017 for all 3 records (SEE TABLE BELOW called D1Merged). I would like for the repeated record to start with the original 2017 model_year and go to 2018 for the next repeated record and 2019 for the third and final repeated record. Then the code would go to the next different record that has repeated values and do the same thing starting with whatever year is originally shown then incrementing from that year until it hits a different repeated record and so on. Remember I only need to increment records that are repeated in the output class, if it isn't repeated it is fine as is.

ORIGINAL feature class before rows are inserted enter image description here

OUTPUT feature class after rows are inserted (D1Merged) enter image description here

The OUTPUT feature class is good except the MODEL_YEAR is repeated when there are multiple records. Somewhere at the end of my code - the insertcursor part - I need to increment model year where necessary.

    import arcpy
    import os
    from arcpy import env
    import numpy

    from datetime import datetime
    startTime = datetime.now()

    arcpy.env.workspace = r"T:\HousinStudy\Scenario1A_Phased_Copied\D1_sorted.gdb"

    arcpy.env.overwriteOutput = True

    fcs = [feature_class names]
    fieldnames = [u'OBJECTID', u'SHAPE', u'APN', u'STREET', u'CITY', u'SITUSZIP', u'JURIS', u'TMSA', u'TOD_CENTER', u'YEARBLT', u'DECADE_CLASS',\
                      u'ZONING', u'LU_DESC', u'LU_CLASS', u'BLDG_DESC', u'SQFEET', u'FAR', u'TMRPA_ID', u'ALT_ZONING', u'ALT_ZONING_DESCRIPTION',\
                      u'DEV_CLASS', u'DU_APPROVED', u'TM', u'TM_NAME', u'PUD', u'PUD_NAME', u'BUBBLE', u'ATOMIC', u'FINAL_MAPPED', u'MF_ID', u'DU_2013',\
                      u'BUILT_DENSITY', u'TOTAL_DENSITY', u'DENSITY_CLASS', u'TMRPA_USE', u'VACANCY_STATUS', u'ZONING_CLASS', u'ZONING_CLASS_DESCRIPTION',\
                      u'RESIDENTIAL_CLASS1', u'RESIDENTIAL_CLASS2', u'TOTAL_ACRES', u'UNCONSTRAINED_ACRES', u'NOTES', u'C_TOD_NAME', u'RSF_1', u'RSF_2', u'RSF_3',\
                      u'RSF_4', u'RSF_5', u'RSF_7', u'RSF_8', u'RSF_9', u'RSF_10', u'RSF_11', u'RSF_12', u'RSF_14', u'modeledUnits', u'Model_Type',\
                      u'Overall_Res_Suitability', u'ScenarioSubArea', u'ZoneName', u'MODEL_FLAG', u'MODEL_YEAR', u'MODEL_POP', u'PHASED', u'PHASE_COUNT',\
                      u'SOURCE', 'SHAPE@', u'PHASE_COUNT1',u'PHASE_COUNT_MINUS1']




    #merge all the features from the environment .gdb into one feature class called NEW

    mergeoutput = r"T:\HousinStudy\Scenario1A_Phased_Copied\D1_sorted.gdb\NEW"
    ##sortoutput = r"T:\HousinStudy\Scenario1A_Phased_Copied\D1_sorted.gdb\NEWNEW"

    ##fld_cnt = "PHASE_COUNT"

    arcpy.Merge_management(fcs, mergeoutput)

    #make a feature layer called "FinalLayer" and calculate PHASE_COUNT null equal to 0
    arcpy.MakeFeatureLayer_management(mergeoutput, "FinalLayer")
    arcpy.SelectLayerByAttribute_management ("FinalLayer","NEW_SELECTION",' "PHASE_COUNT" is NULL ')
    arcpy.CalculateField_management ("FinalLayer", "PHASE_COUNT", 0, "PYTHON_9.3")
    arcpy.SelectLayerByAttribute_management("FinalLayer", "CLEAR_SELECTION")
    arcpy.CopyFeatures_management("FinalLayer", "D1Merged")
    arcpy.AddField_management ("D1Merged", "PHASE_COUNT1",'DOUBLE')
    arcpy.CalculateField_management("D1Merged","PHASE_COUNT1", 1, "PYTHON_9.3")

    arcpy.AddField_management ("D1Merged", "PHASE_COUNT_MINUS1",'DOUBLE')
    arcpy.CalculateField_management("D1Merged","PHASE_COUNT_MINUS1", '[PHASE_COUNT]-[PHASE_COUNT1]')


    print "very powerful"

    #searches through each record if it has a phase 1 or more it will get copied.
    with arcpy.da.SearchCursor("D1Merged", fieldnames) as curs_in:
        flds_in = curs_in.fields  
        idx_cnt = flds_in.index("PHASE_COUNT_MINUS1")

        print "we made it here "
        with arcpy.da.InsertCursor("D1Merged", fieldnames) as curs_out: 
            for row in curs_in:  
                cnt = row[idx_cnt]  
                for i in range(int(0), int(cnt)): 
                    curs_out.insertRow(row)

    print datetime.now() - startTime

enter image description here

Here is some of my modified code which is still not quite working. I get this error " row[idx_year] +=1 TypeError: 'tuple' object does not support item assignment"

with arcpy.da.SearchCursor("D1Merged", fieldnames) as curs_in:
flds_in = curs_in.fields  
idx_cnt = flds_in.index("PHASE_COUNT_MINUS1")
idx_year = flds_in.index("MODEL_YEAR")



print "we made it here "
with arcpy.da.InsertCursor("D1Merged", fieldnames) as curs_out: 
    for row in curs_in:  
        cnt = row[idx_cnt]

        for i in range(int(cnt)):
            curs_out.insertRow(row)
            row[idx_year] +=1
  • 1
    It would be helpful to have a clear example of what your intended output looks like. – Aaron Jan 7 '16 at 4:10
  • So, to get this clear, the first encountered instance of 'phase_count' is unmodified, the 2nd gets the model_year of the first +1 as the model_year and so on.. is this all happening in one table or are you trying to copy the table? – Michael Stimson Jan 7 '16 at 4:17
  • The table on the left is just to show the feature class attribute table before the code runs through and inserts records. The attribute table on the right is what the output looks like. I want this code to continue on that feature class and increment the year where relevant. So lets take those 3 repeated records in the output feature class ( see attribute table on right) and it says MODEL_YEAR 2015, 2015, 2015. I would like it to say MODEL_YEAR 2015, 2016, 2017. Does that make sense? – Damien Jan 7 '16 at 4:34
  • so in the out table the row is repeated 'phase_count' times incrementing the year for each new record... what about 0 and Null instances of 'phase_count'? – Michael Stimson Jan 7 '16 at 4:44
  • You are correct in that the row is repeated 'phase_count' times, but the year is not incremented with how the current code runs. 0 and Null instances remain as is and are not copied. I will add in a quick excel mockup that should clarify what I want the output feature class to look like. – Damien Jan 7 '16 at 4:51
2

here is how you could update your field a posteriori using python dictionnary

 dict = {}
 with arcpy.da.UpdateCursor("D1Merged", ("RECORD_ID","MODEL_YEAR")) as curs: 
  for row in curs:
   if dict.has_key(row[0]):
    dict[row[0]]=dict[row[0]]+1
    row[1]=dict[row[0]]
   else:
    dict[row[0]]=row[1]
   curs.updateRow(row)

within your insert loop, you could increment the year after inserting it, but first you need to copy the row because it comes from an searchcursor (read only)

idx_year = flds_in.index("MODEL_YEAR")
rowout = row
for i in range(int(cnt)):
 curs_out.insertRow(rowout)
 rowout[idx_year] +=1

or use the search cursor vlaue incremented with i

rowout = row
for i in range(int(cnt)):
     rowout[idx_year] = row[idx_year] + i 
     curs_out.insertRow(rowout)
  • When using the first insert loop you provided I get an error in the line row[idx_year] +=1 TypeError: tuple indices must be integers, not list – Damien Jan 7 '16 at 18:54
  • What is the update cursor doing? I put it into the code, but it did not update MODEL_YEAR or anything that I know of. Can the MODEL_YEAR be incremented through just the insert cursor and not update cursor in the examples you provided? – Damien Jan 7 '16 at 19:15
  • idx_year must be the integer value of the position of your field MODEL_YEAR ( -8 if I read well) – radouxju Jan 7 '16 at 20:28
  • the update cursor code should be "standalone" (in case you already have the top table that you illustrate. You can also use one of my suggestion within your existing insertcursor loop. – radouxju Jan 7 '16 at 20:37
  • Okay thank you. I will input one or the other and see what happens. Just to confirm it should say row[idx_year] -8 or row[idx_year] - =8? – Damien Jan 7 '16 at 20:41

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.