대규모 모델 데이터 처리 파이프라인 구축

  1. 【파일명 정제 및 태그 추가】사용자 ID 제거 및 일관된 라벨링 처리, 엑셀 편집 지원 (입력값: 1. 대상 폴더 경로 2. 추가할 라벨명)

*참고: 다중 라벨을 추가해야 할 경우, 영문 쉼표 ","를 사용하여 구분하세요.

import os
import openpyxl
import re

BLACKLISTED_SEGMENTS = ["undefined", "피피", "zly324"]

def sanitize_filenames(directory):
    file_list = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
    processed_files = []

    counter = 1
    for filename in file_list:
        base_name, ext = os.path.splitext(filename)

        # 불필요한 패턴 처리
        if re.search(r'[a-f0-9]{32}', base_name) or '_' not in base_name:
            new_name = f"({counter})"
            counter += 1
        else:
            segments = re.split(r'[_]+', base_name)
            segments.pop(0)  # 첫 번째 조각 제거
            
            # 블랙리스트 필터링
            segments = [seg for seg in segments if seg not in BLACKLISTED_SEGMENTS]
            
            # 숫자 포함 조각 제거
            segments = [seg for seg in segments if not any(char.isdigit() for char in seg)]
            
            # UUID 형식 제거
            while segments and re.search(r'^[a-f0-9\-]{32,}$', segments[-1]):
                segments.pop()
            
            # 짧은 조각 제거
            while segments and len(segments[-1]) <= 4:
                segments.pop()
            
            new_name = '_'.join(segments)

        processed_files.append(new_name + ext)

    return processed_files


def apply_prefix(file_list, prefix):
    prefixed_files = [f"{prefix}_{name}" if not name.startswith(prefix) else name for name in file_list]
    
    # 블랙리스트 필터링
    prefixed_files = ['_'.join([part for part in re.split(r'[_]+', name) if part not in BLACKLISTED_SEGMENTS]) 
                      for name in prefixed_files]
    
    return prefixed_files


def generate_excel_mapping(original_files, processed_files, directory):
    wb = openpyxl.Workbook()
    ws = wb.active
    
    for orig, new in zip(original_files, processed_files):
        ws.append([orig, new])
    
    excel_path = os.path.join(directory, os.path.basename(directory) + ".xlsx")
    wb.save(excel_path)
    
    os.system(f'start "" "{excel_path}"')
    
    return excel_path


def execute_rename_operations(directory, excel_path):
    wb = openpyxl.load_workbook(excel_path)
    ws = wb.active
    
    for row in ws.iter_rows(values_only=True):
        original, target = row
        full_target = os.path.join(directory, target)
        
        if os.path.exists(os.path.join(directory, original)):
            counter = 1
            name, ext = os.path.splitext(target)
            while os.path.exists(full_target):
                target = f"{name} ({counter}){ext}"
                full_target = os.path.join(directory, target)
                counter += 1
            
            os.rename(os.path.join(directory, original), full_target)
    
    print("파일명 재지정 완료")


def main():
    directory = input("처리할 폴더 경로 입력: ")
    original_files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
    sanitized_files = sanitize_filenames(directory)
    
    prefix = input("추가할 접두사 입력: ")
    prefixed_files = apply_prefix(sanitized_files, prefix)
    
    excel_path = generate_excel_mapping(original_files, prefixed_files, directory)
    print(f"엑셀 파일 저장 위치: {excel_path}")
    print("B열 데이터를 수정 후 Excel 파일을 닫아주세요. Enter를 눌러 진행하세요...")
    
    input()
    
    execute_rename_operations(directory, excel_path)


if __name__ == "__main__":
    main()
  1. 【하이픈 통합 처리】첫 번째 하이픈 이후의 하이픈을 공백으로 변환 (입력값: 전체 폴더 경로)
import os
import shutil

def duplicate_directory(src, dst):
    """원본 디렉토리를 복사합니다."""
    try:
        shutil.copytree(src, dst)
    except FileExistsError:
        print(f"백업 디렉토리 '{dst}'가 이미 존재합니다.")

def standardize_filenames(directory):
    """이미지 파일명을 통일화하고 하이픈을 공백으로 변환합니다."""
    for root, dirs, files in os.walk(directory):
        for filename in files:
            if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                first_hyphen = filename.find('-')
                if first_hyphen != -1:
                    before_hyphen = filename[:first_hyphen + 1]
                    after_hyphen = filename[first_hyphen + 1:].replace('-', ' ')
                    new_filename = before_hyphen + after_hyphen
                else:
                    new_filename = filename
                
                if new_filename != filename:
                    original_path = os.path.join(root, filename)
                    new_path = os.path.join(root, new_filename)
                    increment = 1
                    
                    while os.path.exists(new_path):
                        name, ext = os.path.splitext(new_filename)
                        new_filename = f"{name} ({increment}){ext}"
                        new_path = os.path.join(root, new_filename)
                        increment += 1
                    
                    os.rename(original_path, new_path)
                    print(f"파일 {original_path}을 {new_path}로 변경했습니다")

def main():
    input_dir = input("처리할 디렉토리 경로 입력: ")
    
    if not os.path.exists(input_dir):
        print(f"디렉토리 {input_dir}가 존재하지 않습니다.")
        return
    
    backup_dir = os.path.join(input_dir, "_bkp")
    print(f"백업 디렉토리 생성 중: {backup_dir}")
    duplicate_directory(input_dir, backup_dir)
    
    print("백업 디렉토리 내 이미지 파일명 통일화 중...")
    standardize_filenames(backup_dir)
    print("작업 완료")


if __name__ == "__main__":
    main()
  1. 【콤마 변환 작업】이미지 파일명의 콤마를 언더스코어로 변환 (입력값: 전체 폴더 경로)
import os

def replace_commas_interactive():
    path = input("처리할 디렉토리 경로 입력: ")
    modified_files = []
    image_types = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp']
    
    for root, _, files in os.walk(path):
        for filename in files:
            if any(filename.lower().endswith(ext) for ext in image_types):
                new_name = filename.replace(',', '_').replace(',', '_')
                if new_name != filename:
                    os.rename(os.path.join(root, filename), os.path.join(root, new_name))
                    modified_files.append(os.path.join(root, new_name))
    
    return modified_files

modified_files = replace_commas_interactive()
for f in modified_files:
    print(f"변경된 파일: {f}")
  1. 【기본 모델 식별자 추가】첫 번째 언더스코어 앞부분을 복제하고 WJ 접두사 추가 (입력값: 전체 폴더 경로)
import os

def add_prefix_to_images(directory):
    image_formats = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff'}
    
    for root, _, files in os.walk(directory):
        for filename in files:
            if any(filename.lower().endswith(ext) for ext in image_formats):
                parts = filename.split('_')
                if parts:
                    new_name = f'WJ{parts[0].strip()}_{filename}'
                    os.rename(os.path.join(root, filename), os.path.join(root, new_name))
                    print(f'파일명 변경: {os.path.join(root, filename)} → {os.path.join(root, new_name)}')

directory_path = input("처리할 디렉토리 경로 입력: ")
add_prefix_to_images(directory_path)

태그: python openpyxl 파일명_정리 디렉토리_처리 이미지_변환

6월 10일 19:01에 게시됨