How to force Matlab to read files in a folder serially?

一笑奈何 提交于 2019-12-20 03:52:52

问题


I have files in a folder that are numbered from writer_1 to writer_20. I wrote a code to read all the files and store them in cells. But the problem is that the files are not read serially.

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 '\']; 
.
.
.
.
.

Here folders(1).name is writer_1 and folders(2).name is writer_10

I know that dir will return its results as the explorer does but is there any way to force it to go numerically?

I'm training an SVM based on these numbers and this problem is making it difficult.


回答1:


Approach #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)

Approach #2

If you would like to avoid struct2cell, here's an alternative approach -

%// 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)

Please note that strjoin is a recent addition to MATLAB Toolbox. So, if you are on an older version of MATLAB, here's the source code link from MATLAB File-exchange.




回答2:


I don't know of any direct solutions to the problem you are having. I found a solution for a problem similar to yours, 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

Differences are:

  1. You are dealing with directories instead of files
  2. Your directories have other text in their names in addition to the numbers



回答3:


Stealing a bit from DavidS and with the assumption that your folders all are of the form "writer_XX" with XX being digits.

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);

The advantage of this is that it avoids a for loop. In reality it only makes a difference though if you have tens of thousands for folders. (I created 50,000 folders labeled 'writer_1' to 'writer_50000'. The difference in execution time was about 1.2 seconds.




回答4:


Here is a slightly different way (edited to fix bug and implement suggestion of @Divakar to eliminate for loop)

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);


来源:https://stackoverflow.com/questions/25330739/how-to-force-matlab-to-read-files-in-a-folder-serially

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!