2

I have many folders with shapefiles in each of them. I want to use python to go through each folder, add a new field to all the shapefiles containing the folder name.

Any ideas?

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
dhowal
  • 31
  • 6

2 Answers2

2

I would tackle this challenge with Walk. Then loop through the feature classes and add the directory names using an UpdateCursor.

import arcpy, os

# The input (base) directory
workspace = r"C:\tmp"

# Generate an empty list, which will be populated with walk below
fcs = []

# Walk through all directories and directories and list all feature classes
walk = arcpy.da.Walk(workspace, datatype="FeatureClass")
for dirpath, dirnames, filenames in walk:
    for filename in filenames:
        fcs.append(os.path.join(dirpath, filename))

# Loop through the fcs list, add field and add the directory name
for fc in fcs:
    arcpy.AddField_management(fc, field_name = "folder", field_type = "TEXT", field_length = 250)
    dirname = os.path.dirname(fc)
    with arcpy.da.UpdateCursor(fc, "folder") as cursor:
        for row in cursor:
            row[0] = dirname
            cursor.updateRow(row)
Aaron
  • 51,658
  • 28
  • 154
  • 317
  • 1
    Unsure if OP wants full directory path, or just the name of the folder. If just the name is desired, replace dirname = os.path.dirname(fc) with dirname = os.path.basename(os.path.dirname(fc)). – mr.adam Apr 30 '15 at 20:17
  • Nice addition @mr.adam. – Aaron Apr 30 '15 at 20:26
  • That`s right @mr.adam ,well spotted and thank you to @aaron as well for the quick reply. You have both been much help. Any ideas how I can take this one step further and merge all the shaepfiles that have same filenames ? thanks in advance. – dhowal Apr 30 '15 at 20:40
  • Sure. What I would do is put fc_dict = {} right underneath fcs = []. While "walking", if filename in fc_dict.keys(): fc_dict[filename].append(os.path.join(dirpath, filename)) else fc_dict[filename] = [os.path.join(dirpath, filename)]. You'll create a dictionary where the key is the filename and the value is a list of all the corresponding files. At the very end of the script, iterate the dictionary and merge each value. dictionaries are one of the best things about python. https://docs.python.org/2/tutorial/datastructures.html#dictionaries – mr.adam Apr 30 '15 at 20:48
  • like this: for value in fc_dict.values(): arcpy....merge(value,output_fc,etc.) I assume the Merge tools accepts a list for input. – mr.adam Apr 30 '15 at 20:50
  • Thanks @mr.adam , ill give it a try but not sure where to eneter the second bit of code as im quite a newbie . – dhowal Apr 30 '15 at 20:50
  • yes@mr.adam , the merge tools do accept a list . – dhowal Apr 30 '15 at 20:51
  • 1
    @DhowalDalal I would recommend opening a follow-up question if you cannot find a solution in the GIS SE archives. – Aaron Apr 30 '15 at 20:54
  • Okay will do @Aaron . New to this so still need to get the hang of things. Thanks for your help. – dhowal Apr 30 '15 at 20:55
  • yes, it would be misleading to give an answer to your second question here, and it's pretty messy to smash it all into the comments like this. – mr.adam Apr 30 '15 at 20:58
1

as just an outline of ideas: first you can get the folder name with something like:

os.path.relpath(".","..")

or also getting the path of directory and parsing it using 'split'

or you could try using os.walk

then find shapefiles with a matching string (again parsing names as needed) using arcpy.ListFeatureClasses()

you can iterate through

then pass that string to AddField_management:

arcpy.AddField_management (FC, fieldname, fieldtype)

then populate it with CalculateField

arcpy.CalculateField_management (fc, fieldname, data)

JasonBK
  • 610
  • 9
  • 29