質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

Q&A

解決済

1回答

1329閲覧

matlabでの連続処理

shsw228

総合スコア20

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

0グッド

1クリップ

投稿2017/10/31 05:00

編集2017/10/31 05:04

###前提・実現したいこと
カレントディレクトリのcsvを読み込んで解析結果を同じディレクトリに吐き出すプログラムを使用しています。
恥ずかしながら手動でディレクトリを移動させて毎度毎度実行をしているためかなり無駄なことをしているなと自負しております。
(先輩方が代々引き継いだプログラムのようです)

解析するデータを一通り処理し終えたので来年度ではこのようなことをしないために連続で処理したく思います。

###構想
個人的には処理するプログラムをなるべく書き換えたくありません。
被験者のデータが個人で分けられており、一人当たり二回の計測データを持っているので
01.○○(名前)の下に1回目、2回目のフォルダがあってこの被験者フォルダが連番で連なっている形になっています。
(markdownに慣れていないのでわかりにくくて申し訳ありません)

カレントディレクトリを実行するたび変えていくプログラムを外に作るのがいいかと思うのですが、うまく書けません。if構文の考え方の指針などご教授願えませんでしょうか。

###補足情報(言語/FW/ツール等のバージョンなど)
MATLAB 2017a

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

01.○○(名前)、02.○○(名前)などのフォルダは、同一のフォルダ配下にあると仮定します。
ここでは、そのフォルダの名前をdata_folderとしておきます。
01.○○(名前)配下の1回目のフォルダ、2回目のフォルダそれぞれにcsvがいくつあるかわからないので、ここでは複数個あると想定しておきます。

大まかな手順:
0: data_folderの絶対パスを調べる。
1: プログラムのあるフォルダをカレントに設定する。
2: csvファイルへの絶対パスを取得してデータをworkspaceにロードする。
3: プログラムを実行する。
4: 2と3を繰り返す。

準備
MATLABを起動し、プログラムのあるフォルダをcurrentに設定。
data_folderの絶対パスを調べて、エディタにコピーし、folderに格納。
例:folder='C:\Users\humekuru\MATLAB\data_folder';

準備が整ったら、以下を実行してみてください。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% data_folder配下の全個人用フォルダ名を取得 d = dir(folder);d={d([d(:).isdir]).name};d(ismember(d,{'.','..'}))=[]; %% for k=1:length(d) dd = dir(fullfile(folder,d{k})); % 個人用フォルダd{k}配下のデータフォルダ名を取得する。 dd={dd([dd(:).isdir]).name};dd(ismember(dd,{'.','..'}))=[]; for kk=1:length(dd) ddd = dir(fullfile(folder,d{k},dd{kk},'*.csv')); for kkk=1:length(ddd) path_to_csv = fullfile(folder,d{k},dd{kk},ddd(kkk).name);%<--変更 %path_to_csv = fullfile(ddd(kkk).folder, ddd(kkk).name);% <-- オリジナル % csvへのパスが正しいか目で念のため確認。必要なければ削除。 disp(path_to_csv) % csvを読み込んで処理 M=csvread(path_to_csv); your_function(M); % <----- データに対する処理部分 end end end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

投稿2017/10/31 07:41

編集2017/11/08 04:05
WathMorks

総合スコア1582

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shsw228

2017/10/31 09:27

とても丁寧にありがとうございます。 現在スクリプト形式でカレントディレクトリ内のcsvを素直に読んで吐くだけなので、関数化するのが先…ですね 既存のスクリプトの出力先の指定にはpath_to_csvを用いれば出来そうです。 関数にするのはやったことがないので少し調べてみます! ディレクトリ内のフォルダの取得動作自体は理解できました。ありがとうございます。
shsw228

2017/11/07 07:29

dddまでは取得できているんですがpath_to_csv=の代入でこけているようです fullfileの使い方が良くわからず何がおかしいのかわからない状態で止まっています 使用環境に2017と書きましたが研究室で使用しているMATLABは2011でした申し訳ありません。 この差でfullfileの使い方に変化があったのでしょうか…
WathMorks

2017/11/07 07:38

fullfileはファイル区切り(\,/などプラットフォームに依存する)を自動的に挿入してくれるものです。 MacやWindowsで作業する場合、重宝します。OSに合わせていちいち¥や/を変更するのは面倒ですから。2006から導入されているので2011で問題なく動きます。 どのようなエラーがでますか?
shsw228

2017/11/07 13:18

なるほど! 便利ですねfullfile。 エラーは 存在しないフィールド'folder'を参照しています。 と出ています。 ワークスペースでdddにcsvが入っているところまでは確認できています。 folderにはdata_folderを絶対パスで格納してあるのも確認しています。
WathMorks

2017/11/07 15:00 編集

ddd(1)には何が入っていますか?
WathMorks

2017/11/07 15:02

data_folderの下に個人フォルダたち 各個人フォルダの下に1回目と2回目のフォルダ 1回目、2回目、それぞれのフォルダの中にcsv のはずですが。
shsw228

2017/11/07 15:15

フォルダ構造はその通りです 今、自宅(2017)に持ち帰って同じdata_folderに対して同じことをしたらちゃんと通りました。 ddd(1)には一番最後の人の二回目のcsvが読まれてます フィールドはname folder date byte isdir datenum たしか研究室で実行したときのdddの中身にfolderのフィールドがなかったと思います。何があったんでしょうか…
shsw228

2017/11/07 15:28

手持ちのスクリプトを関数にするのがまだできていないのでとりあえずdisp()までで処理が回るかどうか確認しています。 明日もう一度研究室で実行してみて、状況を報告させて頂きます。お手数をおかけします…
shsw228

2017/11/08 02:59 編集

やはりfolderのフィールドが欠けているようです 問題とは直接関係ないとは思うのですが、二つ目のdd={dd([dd(:)~ の記述ってddをセル配列にしているってことでいいんでしょうか? 構造体がよく分かっていないので見当はずれだったら申し訳ないのですが、dirはセル配列じゃないと参照できないということでしょうか?
WathMorks

2017/11/08 02:07

フォルダの階層構造は自宅と同一ですか? また、 folder='????/date_folder'のように、最後が個人フォルダー群を格納したフォルダ名で終わっています?
shsw228

2017/11/08 03:03

同一です。その上の親フォルダをそのままコピーしてます 場所が変わって指定しなおすことを考えましてfolder=uigetdir;を先頭に記述してdata_folderを参照させていますのでそうなっています。
WathMorks

2017/11/08 03:06

folder=uigetdir; を実行してから disp(folder) を実行して、結果を(個人が特定されそうなところは適当に変更して)貼り付けてください。
shsw228

2017/11/08 03:10

>> folder=uigetdir folder = C:\Users\hoge\Desktop\一括処理テスト用\2015.11.28\data_folder >> disp(folder) C:\Users\hoge\Desktop\一括処理テスト用\2015.11.28\data_folder です
WathMorks

2017/11/08 03:15

コマンドウィンドウで d を入力してリターンしてください。 結果はセル配列で {'個人1のフォルダ'} {'個人2のフォルダ},...のようになっていますか?
shsw228

2017/11/08 03:19

なってますね… d = '01.hoge' '02.hoge' '03.hoge' といった形です ワークスペースでも値は1×6のセル配列(六人分でやってます)と出ているので大丈夫だと思います
WathMorks

2017/11/08 03:22

では次にワークスペースで k=1 dd = dir(fullfile(folder,d{k})); dd={dd([dd(:).isdir]).name};dd(ismember(dd,{'.','..'}))=[]; を実行してください。 dd は、最初の人の実験データを格納したフォルダを出力しますか? {'1kaime'},{'2kaime'} のように。
shsw228

2017/11/08 03:29

出力されています。
WathMorks

2017/11/08 03:33

では次に kk=1 ddd = dir(fullfile(folder,d{k},dd{kk},'*.csv')); としてください。 dddはstructですか? ddd.name は'01.hoge\1kaime'の下にあるcsvファイル名ですか?
shsw228

2017/11/08 03:37

dddはstructです。 ddd.nameのcsvファイル名も確かにあっています。 folderフィールドだけが消えます。
WathMorks

2017/11/08 03:40

dd で出力されるものは、フォルダですよね?ファイルじゃないですよね?
shsw228

2017/11/08 03:42

フォルダですね
WathMorks

2017/11/08 03:45

kkk=1 fullfile(folder,d{k},dd{kk},ddd(kkk).name) を実行してみてください。 何がでますか?
shsw228

2017/11/08 03:46

一人目一回目のフォルダ内にあるcsvの絶対パスが返ってきます
WathMorks

2017/11/08 03:48

ではスクリプトのpath_to_csvを path_to_csv=fullfile(folder,d{k},dd{kk},ddd(kkk).name); に変更して、全体を実行してみてください。
WathMorks

2017/11/08 03:50

とりあえず M=csvread(path_to_csv); your_function(M); % <----- データに対する処理部分 の部分をコメントアウトして disp(path_to_csv) を出力させてください。 全部出ていれば成功です。
shsw228

2017/11/08 03:51

無事全部出てきました!
WathMorks

2017/11/08 03:52

お疲れ様です。
shsw228

2017/11/08 03:55

有難うございます。お手数おかけしました。
shsw228

2017/11/21 07:26

何度もすみません、 結局外部スクリプトをループの最後に実行することにしました。 外部スクリプトの一部を切り出して実行したところ最後まで実行することが出来たのですが、全体を実行したところ セルの内容が非セル配列オブジェクトから参照されています。 エラー roop (line 23) ddd = dir(fullfile(folder,d{L},dd{LL},'*.csv'));  と出てきてしまいます。長くプログラムを離れると参照できないなどあるのでしょうか 処理自体は一周15秒ほどです。 一周目は通り、ddの二周目(二回目フォルダ)がうまくいかないという形です
WathMorks

2017/11/21 07:35

とりあえず、 ddd = dir(fullfile(folder,d{L},dd{LL},'*.csv'));  の直前に print(fullfile(folder,d{L},dd{LL},'*.csv')) を追加して、何が出力されるか観察してみてください。 (ddd = dir.... のところはコメントアウトしないで、そのままで。)
shsw228

2017/11/21 07:49

エラー validateHandleToPrint (line 26) 印刷する Figure がありません。 エラー validate (line 17) pj = validateHandleToPrint(pj); エラー print (line 201) pj = validate( pj ); エラー Sasakiroop (line 23) print(fullfile(folder,d{L},dd{LL},'*.csv'));
shsw228

2017/11/21 07:49

ってなりますね…
WathMorks

2017/11/21 07:52

すいません、pythonと間違えました。 printをdispに変更してやってみてください。
shsw228

2017/11/21 07:56

すいません 何も考えず従ってました 略)\一括処理テスト用\2015.11.28 - コピー\data_folder\06.(名前)\2回目*.csv のような形ですね csvを含む~という感じにはなってません このフォルダには一つcsvが入っています。
WathMorks

2017/11/21 08:08

以下のコードは動いたんですよね? % data_folder配下の全個人用フォルダ名を取得 d = dir(folder);d={d([d(:).isdir]).name};d(ismember(d,{'.','..'}))=[]; %% for k=1:length(d) dd = dir(fullfile(folder,d{k})); % 個人用フォルダd{k}配下のデータフォルダ名を取得する。 dd={dd([dd(:).isdir]).name};dd(ismember(dd,{'.','..'}))=[]; for kk=1:length(dd) ddd = dir(fullfile(folder,d{k},dd{kk},'*.csv')); for kkk=1:length(ddd) path_to_csv = fullfile(folder,d{k},dd{kk},ddd(kkk).name);%<--変更 %path_to_csv = fullfile(ddd(kkk).folder, ddd(kkk).name);% <-- オリジナル % csvへのパスが正しいか目で念のため確認。必要なければ削除。 disp(path_to_csv) % csvを読み込んで処理 M=csvread(path_to_csv); your_function(M); % <----- データに対する処理部分 end end end これのどこをどお変更しましたか?
shsw228

2017/11/21 08:40

close all; clear; clc; global workfolder folder=uigetdir('data_folder絶対パス'); % data_folder配下の全個人用フォルダ名を取得 d = dir(folder);d={d([d(:).isdir]).name};d(ismember(d,{'.','..'}))=[]; for L=1:length(d) dd = dir(fullfile(folder,d{L})); % 個人用フォルダd{k}配下のデータフォルダ名を取得する。 dd={dd([dd(:).isdir]).name};dd(ismember(dd,{'.','..'}))=[]; dds = dir(fullfile(folder,d{L},'*.csv')); path_to_target=fullfile(folder,d{L},dds.name); disp(path_to_target); hikensha=csvread(path_to_target,1,0); for LL=1:length(dd) disp(fullfile(folder,d{L},dd{LL},'*.csv')); ddd = dir(fullfile(folder,d{L},dd{LL},'*.csv')); for LLL=1:length(ddd) path_to_csv=fullfile(folder,d{L},dd{LL},ddd(LLL).name); workfolder=fullfile(folder,d{L},dd{LL}); disp(path_to_csv) disp(workfolder) DATA1=csvread(path_to_csv,24,0); DATA2=csvread(path_to_csv,24,0,[24,0,3024,25]); Main end end end このような感じでしょうか 呼び出したいスクリプト(Main)で画像の保存のパス指定に使いたかったのでpath_to_csvを参考にpath_to_targetを追記しています。 Mainの処理のうち頭から1処理を抜き出して別ファイルとして実行したところ最後まで通っているのでループ自体は動くのですが、Main全体を呼び出すとエラーが2週目で出てきて、エラー箇所がddd=となります。
shsw228

2017/11/21 08:50

追記です Main全体を呼び出して実行する際disp(fullfile(folder,d{L},dd{LL},'*.csv'));のときに 非セル配列オブジェクトからセル要素を参照しています。 エラー: Sasakiroop (line 23) disp(fullfile(folder,d{L},dd{LL},'*.csv'));  となることを確認しました。
WathMorks

2017/11/21 08:54

以下を実行して、 target = 個人1フォルダ csv = 1回目のcsv file へのパス csv = 2回目のcsv file へのパス target = 個人2フォルダ csv = 1回目のcsv file へのパス csv = 2回目のcsv file へのパス のように表示されるか確認してみてください。 folder = のところは絶対パスをコピペしてください。 %%%%%%%%%%%%%%%%%%%% close all; clear; clc; %global workfolder folder='data_folder'への絶対パス;<======パスをベタで書いてください。 % data_folder配下の全個人用フォルダ名を取得 d = dir(folder);d={d([d(:).isdir]).name};d(ismember(d,{'.','..'}))=[]; for L=1:length(d) dd = dir(fullfile(folder,d{L})); % 個人用フォルダd{k}配下のデータフォルダ名を取得する。 dd={dd([dd(:).isdir]).name};dd(ismember(dd,{'.','..'}))=[]; dds = dir(fullfile(folder,d{L},'*.csv')); path_to_target=fullfile(folder,d{L},dds.name); disp(['target = ',path_to_target]); %hikensha=csvread(path_to_target,1,0); for LL=1:length(dd) % disp(fullfile(folder,d{L},dd{LL},'*.csv')); ddd = dir(fullfile(folder,d{L},dd{LL},'*.csv')); for LLL=1:length(ddd) path_to_csv=fullfile(folder,d{L},dd{LL},ddd(LLL).name); % workfolder=fullfile(folder,d{L},dd{LL}); disp(['csv = ',path_to_csv]) %disp(workfolder) % DATA1=csvread(path_to_csv,24,0); % DATA2=csvread(path_to_csv,24,0,[24,0,3024,25]); end end end
WathMorks

2017/11/21 08:59 編集

多分、Mainの中でd,dd,dddなどが上書きされているのが原因だと思います。
shsw228

2017/11/21 09:00

ちゃんと出ますね・・・ Mainを探してみます
WathMorks

2017/11/21 09:04

Mainを関数化すれば解決します。
shsw228

2017/11/21 09:06

ありました、本当にちょっとしたことで申し訳ありません・・・・ 外部スクリプトを呼び出す際のワークスペースは共有されるんでしょうか? 関数化することのメリットは独自のワークスペースを持てるという認識でいいんでしょうか
WathMorks

2017/11/21 09:14

スクリプトはワークスペースを共有します。 関数化すると関数内の変数はローカル変数として扱われ、外部からは遮断されます。よって外部の変数と名前が衝突することはありません。
shsw228

2017/11/21 09:19

なるほど、理解できました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問