2

I have a number of polygon feature classes in a geodatabase dataset. The file names are as below:

e.g. IHO1a_xxx-xxxx_ALB,IHO1b_xxx-xxxx_MBES_10m, IHO1b_xxx-xxxx_MBES_2m

I would like to get a python script which will select all files starting with exactly the same first 14 characters in the filename and merge them.

import os,arcpy

# Define location of .gdb
arcpy.env.workspace = "D:\Users\Documents\H-11_Documents for   Reports_Paul\Test_Model_Builder\ICP_Intermediate.gdb\Deliveryxx_Clipped_Po        lygons" 

#Make workspace a variable
workspace = arcpy.env.workspace

List = []

for dirpath, dirnames, filenames in arcpy.da.Walk(workspace, datatype="FeatureClass", type = "Polygon"):
    for filename in filenames:
        if filename.startswith(filename[0:13]):
            List.append(os.path.join(dirpath, filename))
print List
arcpy.Merge_management([filename,filename], 'D:\Users\cadetpn\Documents\H-11_Documents for Reports_Paul\Test_Model_Builder\Temp.gdb\Temp_Data\merge%n%')

##To keep console window open
raw_input("Press enter to exit...")
5
  • 2
    Anything you tried yet? Both topics you need covered here are probably the best examples to start and learn arcpy and python in general as strings/list and a classic merge are the typical beginners task. StackExchange is not meant to provide individual tailored solutions but to help with questions. And you are not really asking a question... – Matte Aug 6 '16 at 12:31
  • What happens when you run your script? – PolyGeo Aug 6 '16 at 13:30
  • ExecuteError: Failed to execute. Parameters are not valid. ERROR 000400: Duplicate inputs are not allowed Failed to execute (Merge) – PCad Aug 6 '16 at 13:31
  • I used model builder to generate a set of polygon feature classes. they are all in one feature dataset. In the data set there will be numerous sets of two feature classes that will have the filename IHO1b_xxx-xxxx exactly matching. I want the script to take each of these two feature classes and merge them. – PCad Aug 6 '16 at 13:41
  • You mention 5 characters in your title, but state 14 characters in your question. Are you after the first 5 or 14 characters? – Aaron Aug 6 '16 at 16:06
6

Python's itertools.groupby is ideally suited for this type of task--in fact it is a one-liner to group by a search string. For example:

import itertools

test = ['IHO1a_xxx-abcd_ALB',
'IHO1a_xxx-abcd_ALB',
'IHO1a_xxx-abcd_ALB',
'IHO1b_xxx-1234_ALB',
'IHO1c_xxx-dcba_ALB',
'IHO1b_xxx-aaaa_ALB',
'IHO1b_xxx-1234_ALB']

groups =  [list(g) for _, g in itertools.groupby(sorted(test), lambda x: x[0:5])]

>>> groups
[['IHO1a_xxx-abcd_ALB', 'IHO1a_xxx-abcd_ALB', 'IHO1a_xxx-abcd_ALB'],
 ['IHO1b_xxx-1234_ALB', 'IHO1b_xxx-1234_ALB', 'IHO1b_xxx-aaaa_ALB'],
 ['IHO1c_xxx-dcba_ALB']]

Then simply iterate over your groups and perform the merge.

4
  • Hi, I can iterate and do a union through the groups and do a union but I would like to control the output filename. for group in groups: arcpy.Union_analysis (group,r"D://Temp.gdb/Clipped_Poly/IHO1b{}Union".format(group[6:13])) I get the error message that the name contains invalid characters – PCad Aug 17 '16 at 12:47
  • @PCad could you please supply the output from r"D://Temp.gd‌​b/Clipped_Poly/IHO1b{‌​}Union".format(group[‌​6:13]))? – Aaron Aug 17 '16 at 15:16
  • 'ExecuteError: ERROR 000210: Cannot create output D:\Users\Clipped_Poly\IHO1b[]Union ERROR 000354: The name contains invalid characters Failed to execute (Union)' – PCad Aug 18 '16 at 4:23
  • Looks like the script is adding trying to add an empty list to the path. What is the output from group[6:13]? – Aaron Aug 18 '16 at 18:34
6

Another method, not one line though but no need to import anything. Kind of good if you need to call a particular group anytime later during the routine.

test = ['IHO1a_xxx-abcd_ALB',
'IHO1a_xxx-abcd_ALB',
'IHO1a_xxx-abcd_ALB',
'IHO1b_xxx-1234_ALB',
'IHO1c_xxx-dcba_ALB',
'IHO1b_xxx-aaaa_ALB',
'IHO1b_xxx-1234_ALB']

dictionary = {}
for x in test:
    group = dictionary.get(x[:5],[])
    group.append(x)
    dictionary[x[:5]] = group

for value in dictionary.itervalues():
    #do the merge here
    print value

['IHO1a_xxx-abcd_ALB', 'IHO1a_xxx-abcd_ALB', 'IHO1a_xxx-abcd_ALB']
['IHO1b_xxx-1234_ALB', 'IHO1b_xxx-aaaa_ALB', 'IHO1b_xxx-1234_ALB']
['IHO1c_xxx-dcba_ALB']
2
4

There were some issues in your code. For example this line:

if filename.startswith(filename[0:13]):

This line is unnecessary because it is checking if itself starts with the first 14 characters of itself, so I have omitted it.

Try this:

import os, arcpy, fnmatch

# Define location of .gdb
arcpy.env.workspace  = r"D:\Users\Documents\H-11_Documents for Reports_Paul\Test_Model_Builder\ICP_Intermediate.gdb\Deliveryxx_Clipped_Polygons"

#Make workspace a variable
workspace = arcpy.env.workspace

List = []

for dirpath, dirnames, filenames in arcpy.da.Walk(workspace, datatype="FeatureClass", type="Polygon"):
    for filename in filenames:
        List.append(os.path.join(dirpath, filename))


# now find the unique patterns
patterns = set([os.path.basename(fl)[:5] for fl in List])

# now loop through List again and merge those that match pattern
for pattern in patterns:
    group = [fl for fl in List if fnmatch.fnmatch(fl, '*' + pattern + '*')]
    arcpy.Merge_management(group, r'D:\Users\cadetpn\Documents\H-11_Documents for Reports_Paul\Test_Model_Builder\Temp.gdb\Temp_Data\merge_{}'.format('pattern'))

##To keep console window open
raw_input("Press enter to exit...")

Also, I would recommend to not have spaces in your folder names.

0

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.