Search code examples
python-3.xrenamefile-renameenumerate

rename images with two different name in specific order


I need to rename 992 image names in the folder with Python. The name of the images should change based on their order. For example

 old: image_1     new: P1_ES_1
 old: image_2     new: P1_ES_2
 old: image_3     new: P1_ES_3
 old: image_4     new: P1_ED_1
 old: image_5     new: P1_ED_2
 old: image_6     new: P1_ED_3
 old: image_7     new: P2_ES_1
 old: image_8     new: P2_ES_2
 old: image_9     new: P2_ES_3
 old: image_10    new: P2_ED_1

...

this is the snippet with minor changes with me provided by @anki, but the problem is new name starts with ED, but it should be ES. any help will appreciated.

import os
import glob

path = 'F:/my_data/imagesResized/'
#path = 'F:/my_data/labelsResized/'

fns = glob.glob(path + '*.png')
fns.sort(key = len)
print(fns)

es_or_ed = 'ES'

for i, fn in enumerate(fns):

    # Check for ED or ES

    if i % 3 == 0 and es_or_ed == 'ES':
        es_or_ed = 'ED'

    elif i % 3 == 0 and es_or_ed == 'ED':
        es_or_ed = 'ES'

    # Create new filename
    new_fn = 'P{}_{}_{}'.format(i // 6 + 1, es_or_ed, i%3+1) 
    #new_fn = 'P{}_{}_{}_{}'.format(i // 6 + 1, es_or_ed, i%3+1,"label")

    # rename...S
    os.rename(fn, os.path.join(path, new_fn + '.png'))

enter image description here


Solution

  • The reason why it starts with ES currently is zero-indexing. When i==0 during the first loop iteration, your code changes the value of es_or_ed to ED.

    I revised your code to account for this, and also to perform a correct sort of your original filenames, as it appears that you do not have leading zeros in filenames and you want 10 to come after 9, not after 1. There is a function that I borrowed from this answer that will sort your list of filenames correctly.

    import os
    import glob
    
    import re
    
    def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
        return [int(text) if text.isdigit() else text.lower()
                for text in _nsre.split(s)]   
    
    path = 'F:/my_data/labelsResized/'
    
    fns = glob.glob(path + '*.png')
    
    es_or_ed = 'ED'
    
    for i, fn in enumerate(sorted(fns, key=natural_sort_key)):
    
        # Check for ED or ES
    
        if (i+1) % 3 == 1 and es_or_ed == 'ED':
            es_or_ed = 'ES'
    
        elif (i+1) % 3 == 1 and es_or_ed == 'ES':
            es_or_ed = 'ED'
    
        # Create new filename
        new_fn = 'P{}_{}_{}'.format(i // 6 + 1, es_or_ed, i%3+1) 
    
        # rename...S
        os.rename(fn, os.path.join(path, new_fn + '.png'))
    

    Result (from code (not shown) where original filename is appended to new filename):

    Screenshot