найти подпапки, которые содержат изображения - PullRequest
2 голосов
/ 14 апреля 2020

Какой самый эффективный способ получить путь к подпапкам, содержащим файлы. Например, если это моя структура ввода.

inputFolder    
│
└───subFolder1
│   │
│   └───subfolder11
│       │   file1.jpg
│       │   file2.jpg
│       │   ...
│   
└───folder2
    │   file021.jpg
    │   file022.jpg

Если я передам getFolders(inputPath), он должен вернуть вывод в виде списка папок, содержащих изображения ['inputFolder/subFolder1/subFolder11','inputFolder/folder2']

В настоящее время я ' Я использую мою библиотеку TreeHandler , которая является просто оберткой os.walk для получения всех файлов.

import os
from treeHandler import treeHandler
th=treeHandler()
tempImageList=th.getFiles(path,['jpg'])
### basically tempImageList will be list of path of all files with '.jpg' extension

### now is the filtering part,the line which requires optimisation.
subFolderList=list(set(list(map(lambda x:os.path.join(*x.split('/')[:-1]),tempImageList))))

Я думаю, что это можно сделать более эффективно.

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 14 апреля 2020
  • Разделение всех частей пути и их повторное соединение, по-видимому, снижает эффективность.
  • Нахождение индекса последнего экземпляра '/' и нарезка работает намного быстрее.

    def remove_tail(path):
        index = path.rfind('/') # returns index of last appearance of '/' or -1 if not present
        return (path[:index] if index != -1  else '.') # return . for parent directory
    .
    .
    .
    subFolderList = list(set([remove_tail(path) for path in tempImageList]))
    
  • Проверено на папках набора данных AWA2 (50 папок и 37,322 изображений).

  • Наблюдается примерно в 3 раза быстрее.
  • Читаемость улучшено с помощью понимания списка.
  • Обработан случай, когда в родительском каталоге есть изображения (что приведет к ошибке в существующей реализации)

Добавление кода, используемого для проверки

import os
from treeHandler import treeHandler
import time

def remove_tail(path):
    index = path.rfind('/')
    return (path[:index] if index != -1  else '.')

th=treeHandler()
tempImageList= th.getFiles('JPEGImages',['jpg'])
tempImageList = tempImageList
### basically tempImageList will be list of path of all files with '.jpg' extension

### now is the filtering part,the line which requires optimisation.
print(len(tempImageList))
start = time.time()
originalSubFolderList=list(set(list(map(lambda x:os.path.join(*x.split('/')[:-1]),tempImageList))))
print("Current method takes", time.time() - start)

start = time.time()
newSubFolderList = list(set([remove_tail(path) for path in tempImageList]))
print("New method takes", time.time() - start)

print("Is outputs matching: ", originalSubFolderList == newSubFolderList)
1 голос
/ 14 апреля 2020
import os
import glob

original_path = './inputFolder/'

def get_subfolders(path):
    return [f.path for f in os.scandir(path) if f.is_dir()]

def get_files_in_subfolder(subfolder, extension):
    return glob.glob(subfolder + '/*' + extension)

files = []
subfolders = [original_path] + get_subfolders(original_path)
while len(subfolders) > 0:
    new_subfolder = subfolders.pop()
    print(new_subfolder)
    subfolders += get_subfolders(new_subfolder)
    files += get_files_in_subfolder(new_subfolder, '.jpg')
...