Clear Filters
Clear Filters

全データの列数を10​0個(100%に時間​正規化)にするにはど​うすればいいでか?

21 views (last 30 days)
Kohei Yoshino
Kohei Yoshino on 21 Apr 2024
Commented: Akira Agata on 23 Apr 2024
30秒間の歩行を想定しています。身体の5箇所に加速度計を装着し、加速度データ、角度データなど9種類のデータが格納されています。
現時点で30秒間の歩行を歩行周期に区切り、28周期に分割するところまで作業が進んでいます。
ここで問題になるがそれぞれの周期データ数がばらついているため、100%に時間正規化(データ数を100個)したいと考えています。
例:A.Thorax(上の図のThoraxを展開)
このようにそれぞれデータ数がばらついております。
このうちの1×1セルの1列に対してはcellfunを使用する方法でデータ数を揃えることはできるのですが、データ数が非常に多いため一括して操作(Thorax, Lumber, Pelvic, LFemoral, LTibia)できたらと思っています。以下のコードはA.Thoraxの6列目だけを抽出してリサンプリングし、平均値まで出したものになります。
data = cell(1, length(A.Thorax)-1)
for i = 1:length(A.Thorax)-1
data{i} = A.Thorax{i}(:,6);
end
% データ数が100のセルを作成
query = cellfun(@(x) 1:length(x)/101:length(x), data, 'uni', false); %データ数を100個に指定
% dataのデータ数を100にリサンプリング
normacc = cellfun(@interp1, data, query, 'uni', false);
avg = arrayfun(@mean, normacc{i})
いい方法があればご教授いただきたいです。

Accepted Answer

Akira Agata
Akira Agata on 22 Apr 2024
interp1 は複数の列に対して各列を一括で内挿できます。このため、以下のようにすると Thorax の各データを 100 行に正規化できます。
for kk = 1:numel(A.Thorax)
data = A.Thorax{kk};
n = size(data, 1);
dataNew = interp1(1:n, data, linspace(1, n));
A.Thorax{kk} = dataNew;
end
同じ処理を Lumber, Pelvic, ... 等に対してやるのですが、いちいちフィールド名ごとに上記のコードを書くのは大変です。そこで、fieldnames 関数でいったん構造体Aのフィールド名一覧を取得しておいて、下記のようにすると一括で処理することができます。
% 構造体Aのフィールド名を取得
fName = fieldnames(A);
% フィールド名それぞれについて上記の処理を実施
for kk1 = 1:numel(fName)
for kk2 = 1:numel(A.(fName{kk1}))
data = A.(fName{kk1}){kk2};
n = size(data, 1);
dataNew = interp1(1:n, data, linspace(1, n));
A.(fName{kk1}){kk2} = dataNew;
end
end
  2 Comments
Kohei Yoshino
Kohei Yoshino on 22 Apr 2024
返信ありがとうございます。やりたいことが一括ででき、時間の効率化が図れそうです。
一点質問があります。上のコードで各列を100行に指定しているのはどの構文になるのでしょうか?
Akira Agata
Akira Agata on 23 Apr 2024
各列を100行に指定(内挿)しているのは interp1 関数を使用して dataNew を作成している行です。具体的には、linspace 関数で 1 から n (=元データの行数)の間で等間隔の100個の点を作成しています(linspaceで生成されるデフォルトのデータ点数が100個のため "linspace(1, n)" としていますが、データ点数を明示的に書くと "linspace(1, n, 100)" となります)。これを使って、元の n行のデータを内挿して100行のデータとしています。
ちなみに interp1 関数のデフォルトの内挿方法は線形内挿です。もしスプライン補間など、より滑らかな内挿方法を試したいときは下記のようにしてください。
dataNew = interp1(1:n, data, linspace(1, n), 'spline'); % スプライン補間の場合

Sign in to comment.

More Answers (0)

Categories

Find more on 内挿 in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!