【问题标题】:How to force Matlab to read files in a folder serially?如何强制 Matlab 连续读取文件夹中的文件?
【发布时间】:2014-08-15 16:56:40
【问题描述】:

我的文件夹中有编号从writer_1writer_20 的文件。我编写了一个代码来读取所有文件并将它们存储在单元格中。但问题是文件不是连续读取的。

folders = dir(Path_training);
folders(ismember( {folders.name}, {'.', '..'}) ) = []; %Remove these two from list
training = [];
    for i = 1:length(folders)
        current_folder = [Path_training folders(i).name '\']; 
.
.
.
.
.

这里folders(1).name 是 writer_1,folders(2).name 是 writer_10

我知道dir 会像资源管理器一样返回它的结果,但是有没有办法强制它以数字形式运行?

我正在根据这些数字训练一个 SVM,这个问题让它变得很困难。

【问题讨论】:

  • 你不能做list = dir(folder)sort(list)吗?那么这只是所需排序标准的问题。
  • 如果您可以重命名文件夹,最简单的解决方案是将它们命名为 writer_01、writer_02...,以便它们自动正确排序

标签: matlab directory dir


【解决方案1】:

我不知道您遇到的问题的任何直接解决方案。 我找到了与您的问题类似的解决方案,here

List = dir('*.png');
Name = {List.name};
S = sprintf('%s,', Name{:});    % '10.png,100.png,1000.png,20.png, ...'
D = sscanf(S, '%d.png,');       % [10; 100, 1000; 20; ...]
[sortedD, sortIndex] = sort(D); % Sort numerically
sortedName = Name(sortIndex);   % Apply sorting index to original names

区别是:

  1. 您处理的是目录而不是文件
  2. 您的目录名称中除了数字之外还有其他文字

【讨论】:

    【解决方案2】:

    方法#1

    %// From your code
    folders = dir(Path_training);
    folders(ismember( {folders.name}, {'.', '..'}) ) = []
    
    %// Convert folders struct to a cell array with all of the data from dir
    folders_cellarr = struct2cell(folders)
    
    %// Get filenames
    fn = folders_cellarr(1,:)
    
    %// Get numeral part and sorted indices
    num=str2double(cellfun(@(x) strjoin(regexp(x,['\d'],'match'),''), fn(:),'uni',0))
    [~,ind] = sort(num)
    
    %// Re-arrange folders based on the sorted indices
    folders = folders(ind)
    

    方法 #2

    如果您想避免使用struct2cell,这里有另一种方法 -

    %// Get filenames
    fn = cellstr(ls(Path_training))
    fn(ismember(fn,{'.', '..'}))=[]
    
    %// Get numeral part and sorted indices
    num=str2double(cellfun(@(x) strjoin(regexp(x,['\d'],'match'),''), fn(:),'uni',0))
    [~,ind] = sort(num)
    
    %// List directory and re-arrange the elements based on the sorted indices
    folders = dir(Path_training);
    folders(ismember( {folders.name}, {'.', '..'}) ) = []
    folders = folders(ind)
    

    请注意,strjoin 是最近添加到 MATLAB Toolbox 中的。因此,如果您使用的是旧版本的 MATLAB,这里是来自 MATLAB File-exchange 的source code link

    【讨论】:

      【解决方案3】:

      从 DavidS 那里窃取一点信息,并假设您的文件夹都是“writer_XX”形式,其中 XX 是数字。

      folders = dir([pwd '\temp']);
      folders(ismember( {folders.name}, {'.', '..'}) ) = [];
      
      % extract numbers from cell array
      foldersNumCell = regexp({folders.name}, '\d*', 'match');
      
      % convert from cell array of strings to double
      foldersNumber = str2double(foldersNumCell);
      
      % get sort order
      [garbage,sortI] = sort(foldersNumber);
      
      % rearrange the structure
      folders = folders(sortI);
      

      这样做的好处是它避免了 for 循环。实际上,如果您有数以万计的文件夹,它只会有所作为。 (我创建了 50,000 个文件夹,标记为 'writer_1' 到 'writer_50000'。执行时间的差异约为 1.2 秒。

      【讨论】:

      • 你不需要str2double(vertcat(foldersNumCell{:}))吗?
      【解决方案4】:

      这里有一种稍微不同的方式(经过编辑以修复错误并实施@Divakar 的建议以消除 for 循环)

      folders = dir(Path_training);
      folders(ismember( {folders.name}, {'.', '..'}) ) = [];
      
      %// Get folder numbers as cell array of strings
      folder_nums_cell = regexp({folders.name}, '\d*', 'match');
      
      %// Convert cell array to vector of numbers
      folder_nums = str2double(vertcat(folder_nums_cell{:}));
      
      %// Sort original folder array
      [~,inds] = sort(folder_nums);
      folders = folders(inds);
      

      【讨论】:

        猜你喜欢
        • 2016-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 2011-04-17
        • 2015-07-21
        • 2020-05-25
        相关资源
        最近更新 更多