文字列と数値を含む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일

0 개 추천

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でカテゴライズし、抽出するのがいいと思います。
しかし、どのようなアウトプットにすればいいかわかっていません。
上記も達成したい場合は新規の質問かコメントにてお願いします。
yuta
yuta 2022년 8월 15일
どちらでも対応可能にしていただきありがとうございます。
また、関数にリンクをつけていただくなど、とてもわかりやすく感謝いたします。
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일
回答に追記しました
yuta
yuta 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

질문:

2022년 8월 15일

댓글:

2022년 8월 15일

Community Treasure Hunt

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

Start Hunting!