2

I have a lot of rasters which have next names structure:

  • 2017-08-02_1011_image.tiff
  • 2017-08-13_5erf_image.tiff
  • 2017-05-02_1555_image.tiff
  • 2017-08-02_1001_image.tiff
  • 2017-08-02_1001_image.tiff
  • 2017-08-06_abc3_image.tiff
  • 2017-08-06_45ei_image.tiff
  • 2017-08-06_0005_image.tiff

I want to mosaic files with same suffix in names (4 symbols before «_image») and set resulted mosaics names with this four symbols – like «1001_mosaic». I try this code:

import arcpy  
from arcpy import env  
from arcpy.sa import*  

env.workspace = "H:\test\Image_names"  
arcpy.env.overwriteOutput = True  
print "Processing mosaic" 

for i in range(1,5):  
   ImgList = arcpy.ListRasters("*"+str(i)+"_image.tiff")  
   arcpy.MosaicToNewRaster_management(ImgList, env.workspace, "image"+str(i)+"_mosaic.tif",  pixel_type="16_BIT_UNSIGNED", cellsize="", number_of_bands="4", mosaic_method="", mosaic_colormap_mode="MATCH")     
   print "Completed!"  

But it mosaics all files with same single symbol before «_image» from 1 to 5:2017-08-06_0005_ image.tiff with 2017-05-02_1555_ image.tiff; 2017-08-02_1011_image.tiff with 2017-08-02_1001_ image.tiff and so on.

I’m new with python.

  • 1
    I would do this slightly differently, with a dictionary of lists. First get all the image names and use the key name.split('_')[1], if the key exists add to the list and if not make a new key, then to assemble the mosaics iterate the keys... that probably sounds like a lot but it's simpler than it sounds. Note it's not a good idea to start an image name with a number. – Michael Stimson Oct 26 '17 at 10:32
3

You question is not really a GIS question, more a question on how to group items in a list. But anyway if you start with a list of the rasters then you can do:

import arcpy
from arcpy import env
env.workspace="H:\test\Image_names"

rasters = arcpy.ListRasters()
values = set(map(lambda x:x.split('_')[-2], rasters)) #Find unique groups
newlist = [[y for y in rasters if y.split('_')[-2]==x] for x in values] #From the rasterlist, create a new list of lists of grouped rasters

for group in newlist:
    if len(group)>1: #Dont mosaic single rasters
        outname='Group_{0}_mosaic.tif'.format(group[0].split('_')[-2])
        arcpy.MosaicToNewRaster_management(input_rasters=group, output_location=env.workspace, raster_dataset_name_with_extension=outname)

Set: A set is an unordered collection with no duplicate elements

Map: Apply function to every item of iterable and return a list of the results

Lambda: Small anonymous functions can be created with the lambda keyword

Split: Return a list of the words in the string, using sep as the delimiter string

Indexing and slicing lists , for example [-2]

  • thank you for your answer! It looks easy but wnen I tried to run it the program gave an error: Runtime error Traceback (most recent call last): File "<string>", line 11, in <module> AttributeError: 'list' object has no attribute 'split' – MayLadyBeetle Oct 26 '17 at 14:13
  • this is line 11: raster_dataset_name_with_extension='{0}_mosaic3.tif'.format(group.split('_')[-2]), pixel_type="16_BIT_UNSIGNED", cellsize="", number_of_bands="4", mosaic_method="", mosaic_colormap_mode="MATCH") – MayLadyBeetle Oct 26 '17 at 14:20
  • Yes, now it works! But as well as solution suggested by Michael Stimson, it generates not only mosaics of images with matched suffixes but also rasters with unique suffix. Could you please recommend how to modifie it to produce only mosaics of rasters? – MayLadyBeetle Oct 26 '17 at 15:23
3

Your input image names all have the format part_part_image.tif, this makes it easier, using string.split('_') breaks up the name into ['part','part','image.tif'] from which we can use the 2nd element (index 1) as the common name.

env.workspace = "H:\test\Image_names"  
arcpy.env.overwriteOutput = True  
ImgList = arcpy.ListRasters()

ImgDict = {} # new empty dictionary
for ThisImg in ImgList:
    ThisSplit = ThisImg.split('_')
    if len(ThisSplit) == 3:
        Key = ThisSplit[1] # The common name as the key for the dict
        if Key in ImgDict:
            ImgDict[Key].append(ThisImg) # append if the key already has values
        else:
            ImgDict[Key] = [ThisImg] # otherwise make a new key

for ThisKey in ImgDict: # iterate every common name
    OutImage = 'Image_{}.tif'.format(ThisKey) # best not to start with a number so put Image first
    arcpy.MosaicToNewRaster_management(ImgDict[ThisKey],arcpy.env.workspace,OutImage,pixel_type="16_BIT_UNSIGNED", cellsize="", number_of_bands="4", mosaic_method="", mosaic_colormap_mode="MATCH")   

A dictionary is like a lookup table, for each unique key a value can be stored, in a key-value pair, this is a very handy way of joining two values together for example:

dict['A'] = 1
dict['B'] = 1
dict['C'] = 10

The 'key' has to be unique but the value does not, so getting the value of either A or B is 1 but the value of C is 10. They're very hand when you get your head around them.. have a read of https://www.tutorialspoint.com/python/python_dictionary.htm which explains better than I can and https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops

  • Thank you for your answer! Your explanations are clear, thanks for them. I tested code and it works good. But as a result I have not only mosaics but also single images with unique keys. Could you suggest a solution how to change the code to solve this? I think about fnmatch, but I don’t know how integrate it to your code properly. – MayLadyBeetle Oct 26 '17 at 14:08
  • How are the unique keys expressed in the file name and what is the output file name? If there's some correlation between the input names and the output name it should be possible. – Michael Stimson Nov 5 '17 at 20:45

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.