Python循环处理一批文件

时间:2019-03-04 10:06:47

标签: python file loops

我想循环处理一批文件,以便一次获取每个子目录的32张图像(由于内存原因,我无法加载所有图像),例如,加载每个目录的img 1-32 img使用它们然后加载img 33-64然后65-96等

我的目录:

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

所以我需要在第一次循环时加载i​​mg1,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 numero 1到32的文件+ dir2 numero 1到32的文件+ dir3 numero 1到32的文件

dir1 numero 33到64的文件+ dir2 numero 33到64的文件+ dir3 numero 33到64的文件在同一循环中

5 个答案:

答案 0 :(得分:3)

os.walk已经返回了一个生成器,该生成器会即时生成一个三元组(目录路径,目录名,文件名)的值,因此您只需要批量生成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

答案 1 :(得分:0)

您可以看看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

答案 2 :(得分:0)

不需要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),但也可以使用其他命令行命令)

答案 3 :(得分:0)

总是使用相同的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

如果您需要跟踪以前的所有列表,则只需复制列表内容即可。

让我知道您是否也想要该实现。

答案 4 :(得分:0)

好吧,我找到了一种方法,虽然不是最漂亮的,但是这里是: 我使用一个集合来知道我已经看过哪个文件,如果我在该文件上就继续,这样它就不计数了。

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