2017-10-16 11 views
2

以下で説明する行列を生成する必要があります。行列の各重複行から最小値と最大値を効率的に取得するにはどうすればよいですか?行列内の重複行の最小値と最大値を効率的に得る方法

レッツは、私が行列として、次のデータを持っていると言う:

A = 

    x  y  z 

    -250 -60 -60 
    -250 -60 -59 
    -250 -60 -58 
    -250 -60  58 
    -250 -60  59 
    -250 -60  60 
    -250 -59 -60 
    -250 -59 -59 
    -250 -59 -58 
    .  .  . 
    .  .  . 
    .  .  . 
    -250  59  58 
    -250  59  59 
    -250  59  60 
    -250  60  58 
    -250  60  59 
    -250  60  60 

重複した行では、私はxとyの同じ値の複数の行を意味します。今度は、次の行列を生成できるように、各重複値から最小値と最大値を求めます。

 x  y  z 


    -250 -60  abs(min(z) - max(z)) % for all x = -250 and y = -60 
    -250 -59  abs(min(z) - max(z)) % for all x = -250 and y = -59 

この行列を効率的に生成するにはどうすればよいですか?あなたはR2015b以上を使用している場合は

+2

この例は3Dマトリックスではありません。 – OmG

+0

3Dマトリックスか3列マトリックスかを明確にしてください。あなたの例は、あなたの質問のタイトルと紹介(編集前)と矛盾します。 – rayryeng

+0

申し訳ありませんが、その3列の行列です。 – MaheshKumar

答えて

5

これは、uniqueと組み合わせたaccumarrayを使用する古典的なケースです。このアプローチの利点は、たとえ答えが問題を解決するのにも同様に良いアプローチだとしても、R2015b以上に限定されないことです。

uniqueを使用して、xy列のすべての一意の行を同時に検索してください。最初の出力でこれらのユニークな行を探し、3番目の出力で各行に一意の整数IDを割り当て、行が属するグループを指定します。 accumarrayには、同じグループに属する一連の値の最大値と最小値の差を検出するカスタムマッピング関数を使用できます。

[Au, ~, ID] = unique(A(:,1:2), 'rows'); 
out = accumarray(ID, A(:,3), [], @(z) abs(min(z) - max(z))); 
out = [Au out]; 

コードの最初の行は、Aの最初の2つの列を使用して、すべてのユニークな行を見つけます。最初の出力Auは、最初の2つの列についてAにあるユニークな行のみの行列を返します。 3番目の出力は、最初の2つの列の各行に整数IDを割り当てます。これにより、同じ行が同じグループに割り当てられるようなマッピングが提供されます。最後にaccumarrayを使用し、グループ化を提供するIDを使用し、3番目の列を使用して、3番目の列のすべての値が同じIDにマッピングされるように、その値の集合に何かを適用します。ここでは、abs(min(z) - max(z))というカスタム関数を適用します。ここで、zは、同じIDに属するすべての3番目の列値をグループ化する配列です。

最後に行列のユニークな行を連結して、その出力をaccumarrayとし、期待される出力を表示します。あなたではなく限られた例を考えると、私たちはMATLABで次の出力を得る:

>> out 

out = 

    -250 -60 120 
    -250 -59  2 
    -250 59  2 
    -250 60  2 

を我々はx = -250, y = -60にマッピングされたグループのために、最小値と最大値が-6060なので、絶対差ので、これが機能するかどうかを確認することができますこれらの要素は120です。残りの一意の行についても同様の手順を実行できます。

+0

明確な答えをありがとう。私は自分の質問を更新しました。私が何をしたのか教えてください。 – MaheshKumar

+1

申し訳ありませんが、なぜこれが機能しないのか理解しました。つまり、抽出された列がAu行列の最初の2つの列に充填され、3番目の列が出力行列になります。私はこれらのデータをプロットしていたので、軸を交換して正しいデータをプロットする必要がありました。 – MaheshKumar

+0

@MaheshKumar正しいです。あなたがそれを理解してうれしい! – rayryeng

3

findgroupssplitapplyを使用します。

[G, IDx, IDy] = findgroups(A(:, 1), A(:, 2)); 
Range = splitapply(@(z) abs(min(z) - max(z)), A(:, 3), G); 

NewMatrix = [IDx, IDy, Range]; 

findgroups

はまさにそれを行い、それが入力のユニークな組み合わせを持っているすべてのグループを検索します。グループ番号を持つベクトルを返し、オプションで各グループの一意の値を返します( IDxおよび IDy、上記)。

splitapplyは、各グループの値に任意の関数を適用します。したがって、関数は、 "グループ1"、次に "グループ2"などのすべてに適用され、cellfunがセル配列内のすべての要素に同じ機能を適用するのと同じように適用されます。

+0

助けてくれてありがとうが、残念ながら私はmatlab R2011bしか持っていない。 – MaheshKumar

関連する問題