0

さまざまなフォルダーやテキスト ファイルからデータを matlab にインポートすることを目指しています。

clear all
main_folder = 'E:\data';
    %Directory of data
TopFolder = dir(main_folder);
    %exclude the first two cells as they are just pointers. 
TopFolder = TopFolder(3:end);
TopFolder = struct2cell(TopFolder);
Name1 = TopFolder(1,:);
    %obtain the name of each folder
dirListing = cellfun(@(x)dir(fullfile(main_folder,x,'*.txt')),Name1,'un',0);
Variables = cellfun(@(x)struct2cell(x),dirListing,'un',0);
FilesToRead = cellfun(@(x)x(1,:),Variables,'un',0);
    %obtain the name of each text file in each folder

これにより、「main_folder」内の各フォルダー内の各テキスト ファイルの名前が提供されます。現在、for ループを使用せずにデータを読み込もうとしています (これを行うには for ループの方が速い場合があることは認識していますが、コンパクトなスクリプトを目指しています)。

for ループで使用する方法は次のとおりです。

for k = 1:length(FilesToRead);
    filename{k} = cellfun(@(x)fullfile(main_folder,Name{k},x),FilesToRead{k},'un',0);
    fid{k} = cellfun(@(x)fopen(x),filename{k},'un',0);
    C{k} = cellfun(@(x)textscan(x,'%f'),fid{k},'un',0);
end

ループをまったく使用しない方法はありますか? おそらくcellfun内のcellfunのようなものですか?

4

2 に答える 2

0

はい。Cはファイル名に依存するfidに依存するため、これはかなり恐ろしいことです。基本的な考え方は次のとおりです。

deal(feval(@(filenames_fids){filenames_fids{1}, filenames_fids{2}, ...
  <compute C>}, feval(@(filenames){filenames, <compute fid>}, ...
  <compute filenames>)));

ファイル名の計算から始めましょう。

arrayfun(@(x)cellfun(@(x)fullfile(main_folder,Name{k},x),FilesToRead{k},...
  'un',0), 1:length(FilesToRead), 'uniformoutput', 0);

これにより、ファイル名の K 行 1 列のセル配列が得られます。これを使用して fid を計算できます。

{filenames, arrayfun(@(k)cellfun(@(x)fopen(x),filenames{k},'un',0), ...
  1:length(FilesToRead), 'uniformoutput', 0)};

K 行 2 列の cell 配列にファイル名と共に fid を貼り付けて、最終的な出力を計算するために渡す準備をします。

{filenames_fids{1}, filenames_fids{2}, ...
  arrayfun(@(k)cellfun(@(x)textscan(x,'%f'), ...
  filenames_fid{2}{k},'un',0), 1:length(FilesToRead), 'uniformoutput', 0)}

次に、最終的な cell 配列を取り込んで、結果が 3 つの異なる変数になるようにします。

[filenames fid C] = deal(feval(@(filenames_fids){filenames_fids{1}, ...
  filenames_fids{2}, arrayfun(@(k)cellfun(@(x)textscan(x,'%f'), ...
  filenames_fid{2}{k},'un',0), 1:length(FilesToRead), 'uniformoutput', 0)}, ...
  feval(@(filenames){filenames, arrayfun(@(k)cellfun(@(x)fopen(x), ...
  filenames{k},'un',0), 1:length(FilesToRead), 'uniformoutput', 0)}, ...
  arrayfun(@(x)cellfun(@(x)fullfile(main_folder,Name{k},x),FilesToRead{k}, ...
  'un',0), 1:length(FilesToRead), 'uniformoutput', 0))));

Errm...保持することを気にしない場合は、おそらくこれを行うより良い方法がありfilenamesますfid. arrayfun の代わりに cellfun を使用すると、より簡潔になるかもしれませんが、私は cellfun があまり得意ではないので、これが私が思いついたものです。forとにかくループバージョンの方がコンパクトだと思います!(また、私はこれを実際にテストしていません。おそらくデバッグが必要になるでしょう)。

于 2012-04-13T10:56:10.857 に答える
0
folder = 'E:\data';
files = dir(fullfile(folder, '*.txt'));
full_names = strcat(folder, filesep, {files.name});
fids = cellfun(@(x) fopen(x, 'r'), full_names);
c = arrayfun(@(x) textscan(x, '%f'), fids);  % load data here
res = arrayfun(@(x) fclose(x), fids);
assert(all(res == 0), 'error in closing files');

ただし、データが csv 形式の場合はさらに簡単になります。

folder = 'E:\data';
files = dir(fullfile(folder, '*.txt'));
full_names = strcat(folder, filesep, {files.name});
c = cellfun(@(x) csvread(x), full_names,  'UniformOutput', false);

これですべてのデータが保存されますc

于 2012-04-13T13:28:13.670 に答える