Цикл Python над партией файлов - PullRequest
0 голосов
/ 04 марта 2019

Я хочу зациклить пакет файлов, чтобы получить 32 изображения каждого подкаталога за раз (я не могу загрузить все изображения из-за памяти), например, загрузить img 1-32 каждого каталога, использовать их, а затем загрузитьimg 33-64, затем 65-96 и т. д.

Мой каталог:

Rootdir
  - dir1
    - img 1
    - img 2
    - img...
  - dir2
    - img 5000001
    - img 5000002
    - img...
  - dir3
    - img 10000001
    - img 10000002
    - img...

Поэтому мне нужно загрузить img1,2, .., 32, 5000001, ... 5000032, 1000001, ... 10000032 в первом цикле, затем img33,34, .., 64, 5000033, ... 5000064, 1000033, ... 10000064 во втором цикле

Есть ли способ сделать это правильно?

Я пытаюсь использовать os.walk, и это позволяет мне зацикливаться на моем каталоге, но я не вижу, как я могу адаптировать этот цикл к моим необходимым 32 пакетам?

for dirName, subdirList, fileList in os.walk(rootdir):
      print('Found directory: %s' % dirName)
      for fname in sorted(fileList):
        img_path = os.path.join(dirName, fname)
        try:
          img = load_img(img_path, target_size=None)
          imgs.append(img)
        except Exception as e:
          print(str(e), fname, i)
      #do something on imgs

РЕДАКТИРОВАТЬ

все ваши комментарии дают мне такие вещи:

dir1 / img1.jpg в dir1 / img32.jpg, затем в dir1 / img33.jpg в dir1 / img64.jpgзатем ...

, затем dir2 / img1.jpg в dir1 / img32.jpg, затем в dir2 / img33.jpg в dir2 / img64.jpg, затем ...

, затем в dir3 / img1.jpgв dir3 / img32.jpg, затем в dir3 / img33.jpg в dir3 / img64.jpg :(

Я пытаюсь достичь:

Файлы dir1 от 1 до 32 + файлы от dir2 от 1 до 32 + файлы от dir3 от 1 до 32, а затем

Файлы dir1 от 33 до 64 + файлы dir2 от 33 до 64 + файлы от dir3 от 33 до 64 в том же цикле

Ответы [ 5 ]

0 голосов
/ 04 марта 2019

Хорошо, я нашел способ, не самый красивый, но вот он: я использую набор, чтобы узнать, какой файл я уже видел, и продолжаю, если я на нем, чтобы он не считался.

number_of_directory = 17
batch_size = 32
seen = set()
for overall_count in pbar(range(data_number // (batch_size * number_of_directory))):
    imgs = []
    for dirName, subdirList, fileList in os.walk(rootdir):
        count = 0
        for fname in sorted(fileList):
          if fname in seen:
            continue
          if count == batch_size:
            break
          img_path = os.path.join(dirName, fname)
          try:
            img = cv2.imread(img_path, cv2.IMREAD_COLOR)
            img = cv2.resize(img, (img_width, img_height))
            imgs.append(np.array(img))
          except Exception as e:
            print(str(e), fname)
          seen.add(fname)
          count +=1
    #Do something with images
0 голосов
/ 04 марта 2019

os.walk уже возвращает генератор, который на лету выдает значения из трех кортежей (dirpath, dirnames, filenames), поэтому вам просто нужно получить фрагмент массива filenames впартии по 32.


Это пример:

import os

# Your root directory path
rootdir = r"Root"

#Your batch size
batch_size = 32

def walk_dirs(directory, batch_size):
    walk_dirs_generator = os.walk(directory)
    for dirname, subdirectories, filenames in walk_dirs_generator:
        for i in range(0, len(filenames), batch_size):
            # slice the filenames list 0-31, 32-64 and so on
            yield [os.path.join(dirname, filename) for filename in filenames[i:i+batch_size]]

# Finally iterate over the walk_dirs function which itself returns a generator
for file_name_batch in walk_dirs(rootdir, batch_size):
    for file_name in file_name_batch:
        # Do some processing on the batch now
        print (file_name)
        pass
0 голосов
/ 04 марта 2019

Нет необходимости в скрипте Python, этого можно добиться с помощью команды tree в командной строке:

C:\Temp_Folder\images>tree /F
C:.
├───dir1
│       image1.jpg
│       image2.jpg
│       image3.jpg
│
├───dir2
│       image1.jpg
│       image2.jpg
│       image3.jpg
│
└───dir3    

Если вы хотите что-то сделать с этими файлами, вы также можете использоватьforfiles:

forfiles /S /M "*.jpg" /c "cmd /c echo @path\@file"

(это только для отображения файлов (echo), но возможны и другие команды командной строки)

0 голосов
/ 04 марта 2019

Как насчет того, чтобы всегда использовать один и тот же список img и обрабатывать его, как только у вас будет 32 изображения?

for dirName, subdirList, fileList in os.walk('c:\\Java\\'):
      print('Found directory: %s' % dirName)
      for fname in sorted(fileList):
        img_path = os.path.join(dirName, fname)
        try:
          img = load_img(img_path, target_size=None)
          imgs.append(img)
          if len(imgs) == 32:
            print("Doing what I have to with current imgs list (add your function here)")
            img = [] # cleaning img list
        except Exception as e:
          print(str(e))
      #do something on imgs

Если вам нужно отслеживать все предыдущие списки, вы можете просто скопировать содержимое списка поверх.

Дайте мне знать, если вы тоже хотите эту реализацию.

0 голосов
/ 04 марта 2019

Вы можете взглянуть на os.walk ()

РЕДАКТИРОВАТЬ: простой пример счетчика

counter = 0
for x in mylist:
    # do something with x 
    todo_list.append(x)
    counter += 1
    if counter % 32 == 0: 
        # do something with todo list
        todo_list = [] # empty todo list for next batch
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...