cell配列をスカラ​ー配列に直すにはどう​すればいいですか?

1×10 cellの中に要素数の異なるデータが格納されています。これら10個の要素の行平均を算出したいと思っています。
そのため
linspace(leulerX{1}, leulerX{2})
を使用したところ、「入力はスカラーでなければなりません」というエラーが表示されました。
cell配列をスカラーに変換する方法はありますか?

2 Commenti

Dyuman Joshi
Dyuman Joshi il 1 Apr 2024
Spostato: Dyuman Joshi il 5 Apr 2024
I am not sure why you are using linspace here.
You can use cellfun to calculate mean of each cell element -
avg = cellfun(@mean, leulerX)
Kohei Yoshino
Kohei Yoshino il 2 Apr 2024
Spostato: Dyuman Joshi il 5 Apr 2024
Thank you. I understand the use of cellfun. I have listed what I would like to implement in the following questions section.

Accedi per commentare.

 Risposta accettata

Atsushi Ueno
Atsushi Ueno il 2 Apr 2024

0 voti

leulerX = cellfun(@(x) rand(randi(100,1,1),1), cell(1,10), 'uni', false) % 実験用サンプルデータ(0-1の乱数)
leulerX = 1x10 cell array
{45x1 double} {89x1 double} {6x1 double} {32x1 double} {14x1 double} {64x1 double} {59x1 double} {66x1 double} {34x1 double} {82x1 double}
rowsizes = cellfun(@size, leulerX, num2cell(ones(1,10))) % 各cell配列要素の行数
rowsizes = 1x10
45 89 6 32 14 64 59 66 34 82
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
for k = 1:min(rowsizes) % 10個とも揃っているのは6行目まで
row_slice = cellfun(@(x,k) x(k), leulerX, num2cell(repmat(k,1,10)));
row_mean_value = mean(row_slice) % これら10個の要素の行平均を算出
end
mean_value = 0.4329
mean_value = 0.4435
mean_value = 0.6105
mean_value = 0.6034
mean_value = 0.6154
mean_value = 0.3809
% cell配列をスカラーに変換する方法はありますか?
[A0,A1,A2,A3,A4,A5,A6,A7,A8,A9] = leulerX{:}; % こういう事でしょう

5 Commenti

Kohei Yoshino
Kohei Yoshino il 2 Apr 2024
返信ありがとうございます。上記の説明理解しました。これらデータは歩行を1周期ごとに区切ったもの(10周期)を想定しております。そのため時間正規化してデータ数(行数)を揃えることをしたいです。そのためにlinspaceで線形補間をしようと考えています。
【やりたいこと】
各cellデータの行数を区間[0, 100]に収める(行数を100個に揃える)
NewA = normalize(A,"scale")
しかし、'scale'は区間[0,1]であるため、他の関数などで[0, 100]に揃えることは可能でしょうか?
Atsushi Ueno
Atsushi Ueno il 3 Apr 2024
Modificato: Atsushi Ueno il 3 Apr 2024
こういう事ですね。色々なリサンプリング関数がありますがToolboxがなくてもinterp1関数が使えます。
period = 2 * pi(); fixed_res = period / 299;
% 長さがバラバラの数値軸(0~2π)を10本束ねてcell配列にする
leulerT = cellfun(@(x) (0:period/randi([200 300],1,1):period)', cell(1,10), 'uni', false)
leulerT = 1x10 cell array
{225x1 double} {278x1 double} {242x1 double} {277x1 double} {252x1 double} {245x1 double} {293x1 double} {210x1 double} {231x1 double} {227x1 double}
% 実験用サンプルデータ(解像度の異なる正弦波)
leulerX = cellfun(@sin, leulerT, 'uni', false)
leulerX = 1x10 cell array
{225x1 double} {278x1 double} {242x1 double} {277x1 double} {252x1 double} {245x1 double} {293x1 double} {210x1 double} {231x1 double} {227x1 double}
% 長さが等しい数値軸(0~2π)を10本束ねてcell配列にする
query = num2cell(repmat(0:fixed_res:period,10,1)',1)
query = 1x10 cell array
{300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double}
% 解像度の異なる正弦波⇒同じ解像度の正弦波データになるようリサンプリングする
NewleulerX = cellfun(@interp1, leulerT, leulerX, query, 'uni', false)
NewleulerX = 1x10 cell array
{300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double} {300x1 double}
aryleulerX = cell2mat(NewleulerX); % 1動作周期の長さが揃ったので行列にも変換できる
Kohei Yoshino
Kohei Yoshino il 3 Apr 2024
ご丁寧な説明ありがとうございます。データ数を揃えて平均値まで算出できました。
NewleulerX = cellfun(@interp1, leulerT, leulerX, query, 'uni', false)
この構文でデータ数を100に設定しましたが、元々のデータが足りないcellに関してはNaN値で補間されてしまいます。これをNaN値ではなく前後のデータ配列から数値で補間するには他のリサンプリング関数が必要ですか?一応、学生用でいくつかのToolboxも持ち合わせておりますのでご教授いただけましたら幸いです。質問が多くて申し訳ありません。
Atsushi Ueno
Atsushi Ueno il 4 Apr 2024
 leulerTとqueryの値域は合致していますか?interp1関数がNaNを返すのは外挿法の指定が無い場合です。leulerTよりqueryの値域が広く外挿が発生していると想定しますが、今やりたい事「1周期毎にバラついたデータ数を揃える」に対して外挿は不要だと思います。歩行1周期毎のデータ数を揃えるのに、前後の周期からデータを持ってくる必要があるのでしょうか?
 上記事例では「歩行1周期」を意識してわざわざ0~2πのサンプル点を設けましたが、interp1関数のサンプル点入力を省略し、規定値1:N(サンプル値の長さ)とする事も可能です。従って、下記の構文を使えば外挿は発生せずNaNも表れないでしょう。
period = 2 * pi();
leulerT = cellfun(@(x) (0:period/randi([200 300],1,1):period)', cell(1,10), 'uni', false)
leulerX = cellfun(@sin, leulerT, 'uni', false)
% query = num2cell(repmat(0:fixed_res:period,10,1)',1)
query = cellfun(@(x) 1:length(x)/301:length(x), leulerX, 'uni', false)
% NewleulerX = cellfun(@interp1, leulerT, leulerX, query, 'uni', false) % 変更前
NewleulerX = cellfun(@interp1, leulerX, query, 'uni', false) % 変更後
Kohei Yoshino
Kohei Yoshino il 4 Apr 2024
お返事ありがとうございます。指定していただいた構文で無事にデータ数を揃えることができました。何度もご対応いただきましてありがとうございました。

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su 行列および配列 in Centro assistenza e File Exchange

Prodotti

Release

R2023b

Community Treasure Hunt

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

Start Hunting!