ArcPy UpdateCursor and Dictionary
You have some problems in the update for. 1) I don't understand why you want to iterate the dictionary, you already have the key in row[0]
. 2) This comparison v == min(v)
it is always false v
is an array and min(v)
is an interger. 3) Related with 2, you are only updating on true case.
So this is a fix to your code,
# Start_End_UpdateAttribute.py
# purpose: For each unique 'Id' value, populate the 'Start_End' field in the valley centerline points shapefile attribute table
# with "start" and "end" using the value of the 'OID_copy' field as criteria
import arcpy
import traceback
arcpy.env.workspace = r'D:/GIS_data/Regional/Washington/ValleyBottom_UC_SF/ValleyBottom_UC_SF_centerlines/Wenatchee'
fc = r'D:/GIS_data/Regional/Washington/ValleyBottom_UC_SF/ValleyBottom_UC_SF_centerlines/Wenatchee' \
r'/VC_ChiwawaRiver_split_verts_Copy.shp'
fields = ['Id', 'OID_copy', 'Start_End']
idDict = {}
cursor = arcpy.da.SearchCursor(fc, fields)
try:
for row in cursor:
id = row[0]
oid = row[1]
stend = row[2]
idDict.setdefault(id, []).append(oid)
except:
print 'An error occurred'
traceback.print_exc()
del cursor
print idDict # output is {key: [value, value], key: [value, value], etc}
cursor2 = arcpy.da.UpdateCursor(fc, fields)
try:
for row in cursor2:
v = idDict[row[0]]
if row[1] == min(v):
row[2] = "Start"
else:
row[2] = "End"
cursor2.updateRow(row)
print 'Updated \'Start_End\' field'
except:
print 'An error occurred - part 2'
traceback.print_exc()
del cursor2
You can use pandas library. If your table is sorted by Id and OID_copy you dont need to use a dictionary:
import arcpy
import pandas as pd
fc = r'C:\GIS\data.gdb\points'
fields = ['Id','Start_End']
df = pd.DataFrame.from_records(data=arcpy.da.SearchCursor(fc,fields), columns=fields) #Create pandas dataframe using da.SearchCursor
l = df.groupby(fields[0]).cumcount().tolist() #https://stackoverflow.com/questions/23435270/how-to-add-sequential-counter-column-on-groups-using-pandas-groupby
l = ['Start' if x%2==0 else 'End' for x in l] #If even cumcount number 'Start' else 'End'
with arcpy.da.UpdateCursor(fc, fields[-1]) as cursor:
for row, startend in zip(cursor, l):
row[0] = startend
cursor.updateRow(row)