2016-03-24 10 views
0

3行と多数の列を持つ大きな行列があります。最初のオカレンス以外のすべての行でゼロを持つ列を削除したい。最初のオカレンス以外のすべての行エントリがゼロである列を削除する

例えば、以下の行列所与:

1 1 0 0 0 0 0 0 
A = 1 0 0 1 0 0 0 0 
    1 0 1 1 0 0 0 0 

それは、このように変換されるであろう:

1 1 0 0 0 
A = 1 0 0 1 0 
    1 0 1 1 0 
+0

あなたの例はまだゼロの列を持っていますが、これは意図的ですか? – excaza

+0

はい、ゼロの開始位置から最初の列を保持したい –

+0

いつもすべてゼロの列が必要ですか? – TroyHaskin

答えて

2

一つのアプローチは次のようになりallを使用し、すべての列をすべての行に沿って検索して、列内のすべての要素これらの列の位置は、findを使用して決定します。すぐにあなたがそうであるように、元の行列のコピーを作成しておくこと、そして私たちは、このような列に遭遇した最初の時間を除いてゼロを持っているすべての列ダンプ:あなたの例では

ind = find(all(A == 0, 1)); 
out = A; 
out(:,ind(2:end)) = []; 

を、我々が得る:

>> out 
out = 
    1  1  0  0  0 
    1  0  0  1  0 
    1  0  1  1  0 

完全なゼロの列がなくても、findは空の配列を返し、空の配列にスライスすると空の配列も生成されます。したがって、最後のコード行での削除手順は効果がなく、前と同じ行列を維持します。制約があなただけの行列の末尾にゼロの列が表示され、それらが有効なデータの間には表示されませんように維持されている場合は


、我々は論理的インデックスでanyallを組み合わせることにより、これを行うことができます:

out = A(:,any(A,1) | diff([false all(A == 0, 1)])); 

マスクの最初の部分が非ゼロのすべての列で構成されるマスクを作成します。この文脈におけるanyは、ゼロでないすべての列を見つける。これは、データの最初の段階で発生し、マスクの前半を構築する必要があります。次の部分はdiffを使用して、前に見た同じall呼び出しによって出力された配列との組み合わせでペアの違いを見つけます。最初の列はゼロではないことが想定されているので、最初の要素がfalseに続いて同じallが呼び出される配列を埋め込むと、の1つだけの論理配列が決定されます。最初にゼロの列が返される点であるゼロ以外の値が返されます。マスク内のこの位置を真であるように設定し、他のゼロ以外の位置に設定して、最終的にマトリックスにサブセットを設定して結果を達成します。

2
b = any(A); 
b(find(b == 0,1)) = 1; 
A=A(:,b) 

OPに一致するように、コメントあたり固定

+0

これは、ゼロが開始されている最初の列も削除します。私は例で説明したようにその列を保持したい! –

+0

完全なゼロのすべての列を削除します。 OPはまた、すべてゼロの列の最初の出現を保持したい。 – rayryeng

+0

それを修正した、私は十分に密接に読んでいない。 – hiandbaii

関連する問題