2017-01-20 9 views
1

多くのオーディオ信号に対して、MirToolBox mirfeatures()関数の出力を含む、いくつかの構造体を含むセルがあります。フィールド名は各構造体で同じです。構造体のセルに同じ名前のフィールドを計算する

したがって、データはこのように見えますが、はるかに大きくなります。 c {1}は最初の構造体、c {2}は2番目の構造体などです。どちらの構造体も同じフィールド名を含みます。

c{1}.field1.field1A=1; 
c{1}.field1.field1B=2; 
c{1}.field1.field1C=3; 
c{1}.field2.field2D.field2E=4; 
c{1}.field2.field2D.field2F=5; 
c{1}.field3=6; 
c{1}.field4.field4A.field4B.field4C=7; 
c{1}.field4.field4A.field4B.field4D=8; 
c{2}.field1.field1A=9; 
c{2}.field1.field1B=10; 
c{2}.field1.field1C=11; 
c{2}.field2.field2D.field2E=12; 
c{2}.field2.field2D.field2F=13; 
c{2}.field3=14; 
c{2}.field4.field4A.field4B.field4C=15; 
c{2}.field4.field4A.field4B.field4D=16; 

各フィールドの平均値を構造全体に計算したいとします。

c{1}.field1.field1A, c{2}.field1.field1A,.. c{n}.field1.field1A=9の平均。

これを行う簡単な方法はありますか?私が実際に使用している構造にはそれぞれ100個のフィールドがあることに注意してください。

おかげ

答えて

0

あなたのセル配列は、構造体配列に変換するためにcell2matを使用して、取得するために(その配列から単一構造体要素から単純ではなく)全体配列上でフィールドにアクセスすることができますコンマで区切られたリスト。フィールドが別の構造体を指している場合、カンマで区切られたリストはコンマで区切られた構造体のリストになります!

{}で囲んでコンマ区切りリストを再度収集し、構造体の各レベルに対してcell2matを再度実行するなどして、同じサイズの構造体配列を得ることができます最初のセル配列。必要なフィールドだけが含まれています。

最終的に十分なレベルで目的のフィールドに到達すると、カンマ区切りのリストとして再度収集し、[]にラップして行列にして、引数として使用できますあなたの機能(例えば、平均)に。

残念なことに、一貫性がないため、一番内側の各フィールドについてこれを行う必要があります。しかし、それはあなたがそれぞれの一意のフィールドごとに単一の操作ですべてのN細胞を処理することを可能にします。

サイズ2のあなたの上のセルを与えられた、と我々は深く、最も外側の、1つのレベルの深さ、二つのレベル、などとしてS0、S1、S2を示している場合は、次のようになります

% Convert outer cell array to struct array representing outermost level 
s0 = cell2mat(c); % -> 1x2 struct array containing the fields: field1, field2, field3, field4 

% field 1 - subfields of interest are 1 level deep 
s1 = cell2mat({s0.field1}); % -> 1x2 struct array containing the fields: field1A, field1B, field1C 
field1A_mean = mean([s1.field1A]) 
field1B_mean = mean([s1.field1B]) 
field1C_mean = mean([s1.field1C]) 

% field 2 - subfields of interest are 2 levels deep 
s1 = cell2mat({s0.field2}); % -> 1x2 struct array containing the field: field2D 
s2 = cell2mat({s1.field2D}); % -> 1x2 struct array containing the fields: field2E, field2F 
field2E_mean = mean([s2.field2E]) 
field2F_mean = mean([s2.field2F]) 

% field 3 - collect at this level 
field3_mean = mean([s0.field3]) 

% field 4 subfields of interest are 3 levels deep 
s1 = cell2mat({s0.field4}); 
s2 = cell2mat({s1.field4A}); 
s3 = cell2mat({s2.field4B}); 
field4C_mean = mean([s3.field4C]) 
field4D_mean = mean([s3.field4D]) 
+0

は、それが変数を持つことが一般的に悪い考えだ、と述べました代わりに配列を持つことができるときに、特に後で変数を反復処理する場合は、「var1 var2 var3」と呼ばれます。さらに、内側のフィールドをグループ化するだけのサブ構造レベルを持つ理由はありません。これは、デザインが複雑になるためです。構造の設計があなたのコントロールから外れていない場合は、構造自体を再設計して、そのような計算をより簡単にすることを検討したいと思います。 (すなわち、各構造体が関心のある '葉'フィールドのみを含む単一の最も外側の構造体配列)。 –

+0

ありがとう、これは非常に役に立ちます。なぜなら、特に後で変数を繰り返し処理する場合は、s1、s2など、またはフィールド名を参照しているかどうかを判断するのが一般的には「var1 var2 var3」という変数を持つのは良い考えです?後者の場合、これらは上の例で使用するためのちょうどダミーの名前でした。 –

+0

いいえ、後者(前者は一時変数を収集する必要があります)です。あなたのデータ構造は不必要に複雑です。あなたの人生を楽にするために、もっと簡単なものを使用してください。 *いずれかの*フィールドはすべてのフィールドが* data *(つまり、親構造体の '1A'、' 1B'、 '1C'、' 2E'、 '2F'、' 3'、 '4C'、' 4D'のダイレクトフィールドを作り残りを破棄します)、* Or * forget構造体についてまとめ、行が項目で、列がフィールドである2Dセル配列を作成します。それで第1の平均「フィールド」の平均([c {:、1}))、第2のものの平均([c {:、2}])などです。 –

関連する問題