Comment parcourir un dossier contenant un grand nombre de fichiers en utilisant Python ?

WBOY
Libérer: 2023-04-25 15:22:08
avant
1246 Les gens l'ont consulté

Lors du traitement des données d'entraînement d'un grand modèle, il est souvent nécessaire de parcourir des dossiers volumineux, qui peuvent inclure des dizaines ou des centaines de millions de fichiers. À ce stade, la fonction de traversée générale de Python sera très lente, comme par exemple. os.walk , glob, path.rglob, etc. Dans le même temps, le temps de parcours global ne peut pas être estimé.

Comment parcourir un dossier contenant un grand nombre de fichiers en utilisant Python ?

Cet article utilise os.scandir de Python et est basé sur l'algorithme de recherche en largeur pour obtenir une traversée contrôlable et efficace des fichiers, et en même temps , affiche le journal de parcours. Prend en charge le filtrage des suffixes, supprime les fichiers cachés et implémente la fonction de parcours des dossiers contenant un grand nombre de fichiers.

os.scandir est une fonction d'itération de répertoire qui renvoie un itérateur d'objets os.DirEntry correspondant aux entrées du répertoire spécifié par chemin. Ces entrées sont générées dans n'importe quel ordre, à l'exclusion des entrées spéciales ». et«…». L'efficacité opérationnelle de os.scandir est supérieure à celle de os.walk Dans le PEP 471, les responsables de Python recommandent également d'utiliser os.scandir pour parcourir les répertoires.

Code source

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
Copier après la connexion

Journal de sortie :

[Info] Le chemin d'initialisation démarre !# 🎜 🎜#[Info] Chemin de l'ensemble de données : /alphafoldDB/pdb_from_uniprot
[Info] dir pdb_from_uniprot : 256it [00:10, 24.47it/s]
[Info] dir 00 : 240753it [00:30 , 7808.36it/s]
[Info] dir 01 : 241432it [00:24, 9975.56it/s]
[Info] dir 02 : 240466it [00:24, 9809.68it/s] #🎜 🎜 #[Info] dir 03 : 241236it [00:22, 10936.76it/s]
[Info] dir 04 : 241278it [00:24, 10011.14it/s]
[Info] dir 05 : 241348it [00:25, 9414.16it/s]

Supplementary

En plus des méthodes ci-dessus, l'éditeur a également vous fournit Nous avons compilé d'autres méthodes Python pour parcourir les dossiers. Si vous en avez besoin, vous pouvez vous y référer

Méthode 1 : parcourir os.walk() et traiter les fichiers directement.

#🎜🎜 #

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
Copier après la connexion
Méthode 2 : Parcourez pathlib.Path().rglob(), vous devez filtrer les fichiers, ce qui est plus rapide. Notez que glob() ne prend pas en charge le parcours récursif

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
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal