文字列と数値を含むcsvファイルを読み込みたい

文字列と数値を含むcsvファイルの読み方についてご教示いただければと思います。
自身で調べてみたものの、全くうまくいかなかったため、質問させていただきます。
今までtest.csvのような、csvファイルを読み込んでいましたが、question.csvのようなデータを読み込む必要が出てきました。
question.csvは、test.csvにGait Cycle ParametersとEventsが増えている形になります。
なお、test.csvは、以下の方法で読み込んでいました。
% データの読み込み
clear,clc;
filepath = "test.csv";
data = readmatrix(filepath);
%2列目のNANの判定をし、前後を引く
idx = isnan(data(:,2));
idx_or =[0;diff(idx)]<0|[diff(idx);0]>0;
% 行番号を見つける
num = find(idx_or);
if mod(length(num),2)
num = [num;height(idx_or)];
end
% numの半分のサイズだけ繰り返し操作
for ii = 1:length(num)/2
A{ii,1} = data(num(2*ii-1):num(2*ii),:);
end
% NANを消し、cell型に格納
B = cellfun(@(x) rmmissing(x,2),A,'UniformOutput',false);
cellfun(@size,B,'UniformOutput',false)
ans = 3×1 cell array
{[ 20 57]} {[13 425]} {[30 161]}
上記の方法では、Gait Cycle ParametersやEventsを読み込めません。
Gait Cycle Parametersは毎回同じ構造で出てくるため、
Value列(4行目の4〜29列)を抽出できればと思っております。
Eventsはデータにより列の数が異なります。
読み込みたいのもはTimeのとこなのですが、それらは
Context(LeftおよびRight)、Name(Foot strikeおよびFoot off)
の 2×2 の計4パターンで出てくるため、それらを判定して4つに分けて抽出できればと思っております。
何卒、よろしくお願いいたします。

5 个评论

Hernia Baby
Hernia Baby 2022-8-15
编辑:Hernia Baby 2022-8-15
ユースケースを想定したいので教えてください。
①question.csv は test.csvと混同して入っていますか?
②以下のようなModel Outputsの欠損部を含む列は消しますか?
yuta
yuta 2022-8-15
コメントありがとうございます。
混同とは、解析を行いたい複数のデータの中に、question.csv形式とtest.csv形式の両者が混じっているということでしょうか?
これらのデータは実験機器から出力したものになるのですが、
  • 歩行計測の時はquestion.csvのような形式(Gait parameterやEventが含まれる)
  • 歩行以外の計測の時は、test.csvのような形式(数値データのみ)
でデータの出力を行っています。
なお、question.csvのGait parameterやEventより下の列に関しては、test.csvと同じ形式になっており、そちらも読み込みたいと考えております。
また、データの読み込み後は、歩行とそれ以外の計測で別の解析を行う予定です。
質問と違う回答になっていたら申し訳ありません。
よろしくお願いいたします。
Hernia Baby
Hernia Baby 2022-8-15
回答ありがとうございます。フォルダわけがなされるということ理解できました。
コメントにて追記した②の部分も回答いただけますと幸いです。
yuta
yuta 2022-8-15
コメントありがとうございます。
説明が不十分で申し訳ありませんでした。
欠損部はデータの解析に使用しません。
しかしながら、これらのデータは全て時系列データになっており、サンプリング周波数が異なります。
以下が具体例です。
  1. Deviceは1000Hzで計測
  2. Model Outputsは100Hzで計測
  3. Trajectoriesは100Hzで計測
また、これらの時系列データは373など(データによって異なる)から始まっており、0秒から出力されているわけではありません。
1行目のFrameが少数第二位までの値、2列目のSub Frameが少数第三位の値になります。
したがって、1の場合は以下のような時間となり、
2、3の場合は以下のような時間となります。
データを合わせて解析する際には、1000Hzデータを100Hzにダウンサンプリングして行う予定になっております。
データの欠損値の列を削除した場合、これらの関係性が崩れなければ、欠損部の列は削除してしまって構わないと考えております。
説明がわかりにくくて申し訳ありません。
よろしくお願いいたします。
Hernia Baby
Hernia Baby 2022-8-15
返答ありがとうございます。
勝手ながらどちらでも対応できるようにしておきました。
ご確認ください。

请先登录,再进行评论。

 采纳的回答

Hernia Baby
Hernia Baby 2022-8-15
编辑:Hernia Baby 2022-8-15
test.csv, question.csvのどちらでもできるようにしました
解説していきます
■ファイルの指定
clc,clear;
% filename = 'test.csv';
filename = 'question.csv';
■キーワードに当てはまる行の探索
 行番号を知りたいので、readlineregexpを用いました
 後々のため、最後の行番号もstartIndexに格納します
str = readlines(filename);
keywords = ["Gait Cycle Parameters","Events","Devices","Model Outputs","Trajectories"];
for ii = 1:length(keywords)
startIndex{ii,1} = find(~cellfun('isempty',regexp(str,keywords(ii))));
end
startIndex = [cell2mat(startIndex);height(str)];
■読み込み
 readmatrixのオプション'Range'を活用しています
 何行から何行まで読むといったものです
 オプション指定が文字なのでsprintfで文字にしています
 後々の操作のため、キーワードの行+2行目 から読み込ませてます
 (※1行目だけにある100とかの数字が邪魔なのでそこを読まないようにしています)
num = length(startIndex)-1;
for ii = 1:num
T{ii} = readmatrix(filename,'Range',sprintf('%i:%i',startIndex(ii)+2,startIndex(ii+1)));
end
■NaNを取り除く
 rmmissingだとNaNが1つでもあると消してしまうので自作しました
T = cellfun(@(x) MyFcn(x),T,"UniformOutput",false);
■コメントで質問した②の該当箇所も消してサイズを見る
 一応やっておきます
cellfun(@(x) size(rmmissing(x,2)),T,'UniformOutput',false)
ans = 1×5 cell array
{[26 1]} {[18 1]} {[21 2]} {[13 425]} {[30 161]}
■Eventsについて(追記)
 keywordsの順番が変わらない前提で今回書いています
 Aからcellで読み込み7列目以降を消しました
ii = 1;
A = readcell(filename,'Range',sprintf('%i:%i',startIndex(ii)+2,startIndex(ii+1)-2));
A(:,7:end) = [];
 テーブル型に変更します
A = cell2table(A(2:end,:),"VariableNames",A(1,:));
 ContextとNameを抽出します
 今回、Foot strikeがないのでSingle Supportで代用しています
Context = ["Left","Right"];
Name = ["Single Support","Foot Off"];
for ii = 1:2
for jj = 1:2
B{ii,jj} = table2array(A(A.Context == Context(ii) & A.Name == Name(jj),'Value'));
end
end
B
B = 2×2 cell array
{[0.2800]} {[50]} {[0.3200]} {[72]}
 Tの最終列に加えておきますか
T{length(T)+1} = B
T = 1×6 cell array
{26×1 double} {18×1 double} {21×57 double} {13×569 double} {30×161 double} {2×2 cell}
■関数の説明
 idx1 : 全ての行がNaNである部分を除外
 idx2 : 全ての列がNaNである部分を除外
function y = MyFcn(x)
idx1 = ~all(isnan(x),2);
idx2 = ~all(isnan(x),1);
y = x(idx1,idx2);
end

4 个评论

Hernia Baby
Hernia Baby 2022-8-15
Context(LeftおよびRight)、Name(Foot strikeおよびFoot off)
の 2×2 の計4パターンで出てくるため、それらを判定して4つに分けて抽出できればと思っております。
---------
上記を失念していました。
この場合はreadtableでカテゴライズし、抽出するのがいいと思います。
しかし、どのようなアウトプットにすればいいかわかっていません。
上記も達成したい場合は新規の質問かコメントにてお願いします。
どちらでも対応可能にしていただきありがとうございます。
また、関数にリンクをつけていただくなど、とてもわかりやすく感謝いたします。
Eventsについて、可能であればお願いできれば幸いです。
アウトプットに関しましては、
先ほどの読み込みに組み込めたりするのでしょうか?それとも別でreadtableを使用する形になるのでしょうか?
いずれにしても、
以下のようなDubblle型
Left_strike = [4.38 5.47 6.47 7.48 8.55];
Left_off = [5.15 5.97 7.1 8.07];
Right_strike = [4.91 5.91 6.97 7.95 9.01];
Right_off = [5.63 6.63 7.59 8.69];
もしくはそれらをまとめたCell配列でアウトプットできればと考えております。
Events = {Left_strike, Left_off, Right_strike, Right_off}
Events = 1×4 cell array
{[4.3800 5.4700 6.4700 7.4800 8.5500]} {[5.1500 5.9700 7.1000 8.0700]} {[4.9100 5.9100 6.9700 7.9500 9.0100]} {[5.6300 6.6300 7.5900 8.6900]}
お手数おかけしますが、何卒よろしくお願いいたします。
Hernia Baby
Hernia Baby 2022-8-15
回答に追記しました
すいません、私の説明が不十分でした。
Eventsはこちらの方を指しておりました。
ii = 2;
A = readcell(filename,'Range',sprintf('%i:%i',startIndex(ii)+2,startIndex(ii+1)-2));
A(:,5:end) = [];
A = cell2table(A(2:end,:),"VariableNames",A(1,:));
Context = ["Left","Right"];
Name = ["Foot Strike","Foot Off"];
for ii = 1:2
for jj = 1:2
B{ii,jj} = table2array(A(A.Context == Context(ii) & A.Name == Name(jj),'Time (s)'));
end
end
しかし、Hernia Baby様のご教示いただいたものに少し修正を加えることで、おそらく読み込みができたかと思います。
ありがとございます!
私の説明が至らない部分が多くあり、お手数おかけいたしました。
いつもご丁寧に説明いただきありがとうございます。
今後とも、よろしくお願いいたします。

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 データ型の識別 的更多信息

产品

版本

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!