-1

各行がm x nゼロと各行の同じ値で構成される行列があります。

例は次のとおりです。

M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0]

この例では、最初の列は0s と-0.6、2 番目01.8、3 番目などで構成さ-2.3れています。

そのような場合、m を 1 に減らしたい (指定された行列からベクトルを取得する) ため、この例ではベクトルは次のようになります。[-0.6 1.8 -2.3 3.4 -3.8 -4.3]

そのような行列からベクトルを取得する最良の方法を知っている人はいますか?

ありがとうございました!

4

5 に答える 5

1

不明な数の非ゼロとゼロがある場合、問題を解決する 1 つの方法は、最初にゼロを NaN に置き換えてから、max や min などを使用してデータを見つけることです。

%# create an array
M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0];

%# replace zeros with NaN
M(M==0) = NaN;

%# get, for each column, the number
numbers = max(M,[],1)

numbers =

    -0.6000    1.8000   -2.3000    3.4000   -3.8000   -4.3000

編集

これが私が質問を理解した方法です。

以下は、ソリューションを取得するためのより Matlab に似た (ただしより長い) 方法です。

%# create an array
    M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0];

%# find the non-zero entries
[r,c] = find(M);

%# only take one entry per column
[uniqueCols, sortIdx] = unique(c);

%# fix the rows correspondingly
uniqueRows = r(sortIdx);

%# convert to index
idx = sub2ind(size(M),uniqueRows,uniqueCols);

%# get the numbers per column (transpose as needed)
numbers = M(idx)

numbers =

   -0.6000
    1.8000
   -2.3000
    3.4000
   -3.8000
   -4.3000
于 2010-04-15T13:26:50.453 に答える
1

関数SUMを使用するワンライナーを次に示します。

nonZeroColumnValues = sum(M)./sum(M ~= 0);

これは、各列から繰り返されるゼロ以外の値を含む 1 行 n 列のベクトルを返します。これは、各列を合計し、その結果を各列のゼロ以外の値の数で割ることによって行われます。列にゼロ以外の値がない場合、その列の結果はNaNになります。

M質問のサンプル マトリックスを使用した例を次に示します。

>> M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0]

M =

   -0.6000    1.8000   -2.3000         0         0         0
         0         0         0    3.4000   -3.8000   -4.3000
   -0.6000         0         0    3.4000         0         0

>> nonZeroColumnValues = sum(M)./sum(M ~= 0)

nonZeroColumnValues =

   -0.6000    1.8000   -2.3000    3.4000   -3.8000   -4.3000
于 2010-04-15T15:26:04.487 に答える
0

これは実際には疎行列ではありません。MATLAB のスパース行列はそのように定義されています。sparse 関数または spdiags 関数を使用してその行列を定義する場合、ゼロ要素を格納する必要はなく、非ゼロ要素のみを格納する必要があります。もちろん、MATLAB は、これらの真のスパース行列を他の標準 double 配列と組み合わせて使用​​する方法を知っています。

最後に、真のスパース行列は、通常、これよりもはるかにスパースです。または、スパース ストレージ フォームをまったく使用する必要はありません。

いずれにせよ、ANY 行列の非ゼロ要素のみが必要な場合は、次のようにすることができます。

NZ = M(M ~= 0);

あるいは、

NZ = M(find(M));

どちらも非ゼロを列ごとに並べます。これは、数値が MATLAB の行列に格納される方法であるためです。

NZ = M(find(M))
NZ =
         -0.6
         -0.6
          1.8
         -2.3
          3.4
          3.4
         -3.8
         -4.3

あなたの質問では、行ごとにこれを行う方法を尋ね、最初の行でゼロ以外の要素を抽出し、次に2行目などを抽出しました.

これは、最初に配列を転置することによって最も簡単に実行できます。したがって、次のようなことをするかもしれません...

NZ = M.';
NZ = NZ(find(NZ))
NZ =
         -0.6
          1.8
         -2.3
          3.4
         -3.8
         -4.3
         -0.6
          3.4

私が使ったことを見てください。要素が複雑な場合に備えて、転置を行います。

于 2010-04-15T13:24:03.353 に答える
0

OPが本当に一意でもある非ゼロ要素を見つけたい場合は、Jonasが提案するよりもはるかに優れた方法があります。

論理的な解決策は、ゼロ以外の要素を最初に見つけることです。次に、関数 unique を適用します。だからこれをしてください:

unique(M(find(M)))

これらの要素を特定の順序で見つけることが目標である場合は、その順序を目標で明示的に定義する必要があります。

于 2010-04-15T14:36:02.790 に答える
0

M = M(M~=0)

また

M(find(M))

SOリーダーのコードをフォーマットする方法を学んでください。

EDIT @Jonas は、OP が M からのゼロ以外の各要素の 1 回の出現のみを必要とすることを示唆しています。これを取得するには、前述の提案のいずれかを でラップしてみてくださいunique()

unique(M(M~=0))
于 2010-04-15T12:33:48.860 に答える