>  기사  >  백엔드 개발  >  Python을 사용하여 많은 수의 파일이 포함된 폴더를 반복하는 방법은 무엇입니까?

Python을 사용하여 많은 수의 파일이 포함된 폴더를 반복하는 방법은 무엇입니까?

WBOY
WBOY앞으로
2023-04-25 15:22:081243검색

대형 모델의 학습 데이터를 처리할 때 수천만 또는 수억 개의 파일이 포함될 수 있는 대규모 폴더를 순회해야 하는 경우가 많습니다. 이때 os.walk, glob, path.rglob 등 동시에 전체 순회 시간을 추정할 수 없습니다.

Python을 사용하여 많은 수의 파일이 포함된 폴더를 반복하는 방법은 무엇입니까?

이 기사는 Python의 os.scandir을 사용하고 너비 우선 검색 알고리즘을 기반으로 하여 제어 가능하고 효율적인 파일 탐색을 달성하는 동시에 순회 로그를 출력하고 접미사 필터링을 지원하며 숨겨진 파일을 제거합니다. 많은 수의 파일을 포함하는 파일을 탐색합니다.

os.scandir은 path로 지정된 디렉터리의 항목에 해당하는 os.DirEntry 개체의 반복자를 반환하는 디렉터리 반복 함수입니다. 이러한 항목은 특수 항목 ‘.’을 제외하고 임의의 순서로 생성됩니다. ;&헬립 ;’. os.scandir의 운영 효율성은 os.walk의 운영 효율성보다 높습니다. PEP 471에서 Python 관계자는 os.scandir을 사용하여 디렉터리를 탐색할 것을 권장합니다.

소스 코드

def traverse_dir_files_for_large(root_dir, ext=""):
    """
    列出文件夹中的文件, 深度遍历
    :param root_dir: 根目录
    :param ext: 后缀名
    :return: 文件路径列表
    """
    paths_list = []
    dir_list = list()
    dir_list.append(root_dir)
    while len(dir_list) != 0:
        dir_path = dir_list.pop(0)
        dir_name = os.path.basename(dir_path)
        for i in tqdm(os.scandir(dir_path), f"[Info] dir {dir_name}"):
            path = i.path
            if path.startswith('.'):  # 去除隐藏文件
                continue
            if os.path.isdir(path):
                dir_list.append(path)
            else:
                if ext:  # 根据后缀名搜索
                    if path.endswith(ext):
                        paths_list.append(path)
                else:
                    paths_list.append(path)
    return paths_list

출력 로그:

[정보] 초기화 경로 시작!
[정보] 데이터 세트 경로: /alphafoldDB/pdb_from_uniprot
[정보] dir pdb_from_uniprot: 256it [00:10, 24.47it/ s ]
[정보] dir 00: 240753it [00:30, 7808.36it/s]
[정보] dir 01: 241432it [00:24, 9975.56it/s]
[정보] dir 02: 240466it [00:24 , 9809.68it/s]
[정보] dir 03: 241236it [00:22, 10936.76it/s]
[정보] dir 04: 241278it [00:24, 10011.14it/s]
[정보] dir 05: 241348it [ 00:25, 9414.16it/s]

Supplement

편집기는 위의 방법 외에도 폴더 탐색을 위한 다른 Python 방법도 컴파일했습니다. 필요한 경우 참조할 수 있습니다

방법 1: os.walk()로 Traverse를 전달하고 파일을 직접 처리

def traverse_dir_files(root_dir, ext=None, is_sorted=True):
    """
    列出文件夹中的文件, 深度遍历
    :param root_dir: 根目录
    :param ext: 后缀名
    :param is_sorted: 是否排序,耗时较长
    :return: [文件路径列表, 文件名称列表]
    """
    names_list = []
    paths_list = []
    for parent, _, fileNames in os.walk(root_dir):
        for name in fileNames:
            if name.startswith('.'):  # 去除隐藏文件
                continue
            if ext:  # 根据后缀名搜索
                if name.endswith(tuple(ext)):
                    names_list.append(name)
                    paths_list.append(os.path.join(parent, name))
            else:
                names_list.append(name)
                paths_list.append(os.path.join(parent, name))
    if not names_list:  # 文件夹为空
        return paths_list, names_list
    if is_sorted:
        paths_list, names_list = sort_two_list(paths_list, names_list)
    return paths_list, names_list

방법 2: pathlib.Path().rglob()을 통해 트래버스합니다. 파일을 필터링해야 하므로 속도가 더 빠릅니다. glob()은 재귀 순회를 지원하지 않습니다

def traverse_dir_files(root_dir, ext=None, is_sorted=True):
    """
    列出文件夹中的文件, 深度遍历
    :param root_dir: 根目录
    :param ext: 后缀名
    :param is_sorted: 是否排序,耗时较长
    :return: [文件路径列表, 文件名称列表]
    """
    names_list = []
    paths_list = []
    for path in list(pathlib.Path(root_dir).rglob("*")):
        path = str(path)
        name = path.split("/")[-1]
        if name.startswith('.') or "." not in name:  # 去除隐藏文件
            continue
        if ext:  # 根据后缀名搜索
            if name.endswith(ext):
                names_list.append(name)
                paths_list.append(path)
        else:
            names_list.append(name)
            paths_list.append(path)
    if not names_list:  # 文件夹为空
        return paths_list, names_list
    if is_sorted:
        paths_list, names_list = sort_two_list(paths_list, names_list)
    return paths_list, names_list

위 내용은 Python을 사용하여 많은 수의 파일이 포함된 폴더를 반복하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제