1

I am trying to use an update cursor on a shapefile to calculate a row from a dictionary and must be missing something very simple. below is my code

so my dictionary is called adict

adict = {'source': {0: u'SUN', 1: u'DAN'}, u'WORK_TYPE': {0: u'FRA', 1: u'UKB'}, u'API_NUM': {0: '422973', 1: '422873'}

And i am trying to calculate worktype in my shapefile.

with arcpy.da.UpdateCursor(myshapefile, ['API_NUM','WORK_TYPE']) as cursor:
    for row in cursor:
        if row[0] in adict['API_NUM'].values():
            row[1]=adict[row[0]]
            cursor.updateRow(row)
        else:
            print 'no'

i'm trying to set the row value on the shapefile to the corresponding dictionary value.


I am trying to calculate my work_type column in the shapefile with the work_type value from the dictionary based on the matching API_NUM, so for api = 422873, the worktype would be UKB.

If i were using geopandas, i would convert the dict to a dataframe and merge on api. Using arcpy right now i am iterating through both sets of data and calculating the work value from the corresponding dict data, but because there are so many records in both sets, it's taking a while using that method. so i thought a dictionary may be faster. I know i could convert to array, then to a table, but that just seems like a bunch of steps.

  • seems to be more like a Python problem, that belongs to StackOverflow site – adamczi Aug 4 '18 at 17:25
  • I had it tagged arcpy and python and one of the admins removed the python tag for a reason i don't know. – Messak Aug 4 '18 at 17:28
2

Per your additional comments, I think you need to reconstruct your dictionary, and then pull the values from your new dict using the field value from API_NUM. See my # Comments in the code below which hopefully give a bit of detail what the changed lines are doing.

adict = {'422973': {'source': 'SUN', 'WORK_TYPE': 'FRA'}, '422873': {'source': 'DAN', 'WORK_TYPE': 'UKB'}}

with arcpy.da.UpdateCursor(myshapefile, ['API_NUM','WORK_TYPE']) as cursor:
    for row in cursor:
        if row[0] in adict: # Does the API_NUM exist as a key in the dictionary?
            row[1] = adict[row[0]]['WORK_TYPE'] # Find the WORK_TYPE for the current row's API_NUM
            cursor.updateRow(row)
        else:
            print 'API_NUM {} not in dictionary'.format(row[0])

I also find that when working with large dictionaries (especially dictionaries of dictionaries) that it is often clearer to put different entries on new lines:

adict = {
         '422973': {'source': 'SUN', 'WORK_TYPE': 'FRA'}, 
         '422873': {'source': 'DAN', 'WORK_TYPE': 'UKB'}
        }
  • Brilliant and thank you, works perfectly. i restructured my dictionary like you recommended and yes, it makes much more sense. – Messak Aug 4 '18 at 17:48
0

I actually think i solved it,

with arcpy.da.UpdateCursor(myshapefile, ['API_NUM','WORK_TYPE']) as cursor:
for row in cursor:
    if row[0] in adict['API_NUM'].values():
        row[1]=adict['WORK_TYPE'][0]  ## <- here is what i was missing
        cursor.updateRow(row)
    else:
        print 'no'
  • Do you want the row[1] value to always be set to 'FRA' ? As that is what you are pulling from your dictionary, every time. – Midavalo Aug 1 '18 at 23:52
  • you sir, are correct, which is wrong, on my part. How would i write it correctly? – Messak Aug 3 '18 at 12:33
  • Are you wanting to use the value from row[0] to select the WORK_TYPE from the dictionary? – Midavalo Aug 4 '18 at 3:04
  • yes, i am trying to calculate my work_type column in the shapefile with the work_type value from the dictionary based on the matching API_NUM – Messak Aug 4 '18 at 11:17
  • So if your API_NUM is 422873 (from your dictionary above) what would you expect your WORK_TYPE to be, and why? – Midavalo Aug 4 '18 at 15:12

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.