2

私はマトリックスAを持っています:

A= [ 1 1 0 2 2 2 2 0 0 3 3 0 0;
     0 1 1 0 0 2 2 2 2 3 3 0 0 ];

そして、別の行列 B を作成して、この行列に元の行列 A の値の出現回数が含まれるようにします。つまり、 のii各行には、A の対応する列でB何回ii出現するかが含まれます。数値 0 は無視できます。

例: A の 2 列目では、数値 1 のみが発生し、具体的には 2 回発生します --> したがって、B(1,2) = 2 および B(other,2) = 0 です。

私の例の行列 A の場合、出力は次のようになります。

Res = [ 1 2 1 0 0 0 0 0 0 0 0 0 0;
        0 0 0 1 1 2 2 1 1 0 0 0 0;
        0 0 0 0 0 0 0 0 0 2 2 0 0 ];
4

4 に答える 4

2

これは、(過小評価されている) accumarrayの機会でもあります。

A= [ 1 1 0 2 2 2 2 0 0 3 3 0 0;
     0 1 1 0 0 2 2 2 2 3 3 0 0 ];
N = size(A,2);
result = zeros(max(A(:)),N);

for ii=1:N
    s = accumarray(nonzeros(A(:,ii)),1);
    result(1:numel(s),ii) = s;
end

accumarray が 1 回の呼び出しですべてを実行できないことだけが残念です :(

編集

1 回の accumarray 呼び出しですべてを取得しました: :p

A= [ 1 1 0 2 2 2 2 0 0 3 3 0 0;
     0 1 1 0 0 2 2 2 2 3 3 0 0 ];
N = size(A);
C = repmat(1:N(2),N(1),1);

result = accumarray([A(:)+1 C(:)], 1);
result = result(2:end,:)

EDIT2

3 次元の入力行列がある場合は、まずそれを 2 次元の行列に変換してから、上記を使用して処理するのが最も簡単です。次のコードは、この変換を行います。

% example data:
A3d = repmat(A,[1 1 2])
A2d = reshape(permute(A3d,[1 3 2]),[],size(A3d,2))

結果:

A3d(:,:,1) =
 1     1     0     2     2     2     2     0     0     3     3     0     0
 0     1     1     0     0     2     2     2     2     3     3     0     0
A3d(:,:,2) =
 1     1     0     2     2     2     2     0     0     3     3     0     0
 0     1     1     0     0     2     2     2     2     3     3     0     0


A2d =
 1     1     0     2     2     2     2     0     0     3     3     0     0
 0     1     1     0     0     2     2     2     2     3     3     0     0
 1     1     0     2     2     2     2     0     0     3     3     0     0
 0     1     1     0     0     2     2     2     2     3     3     0     0
于 2012-07-23T08:28:58.807 に答える
1

使用できます

A= [ 1 1 0 2 2 2 2 0 0 3 3 0 0;
     0 1 1 0 0 2 2 2 2 3 3 0 0 ];


cell2mat(arrayfun(@(b) sum(A == b),nonzeros(unique(A)), 'UniformOutput', false))

これにより、

ans =

     1     2     1     0     0     0     0     0     0     0     0     0     0
     0     0     0     1     1     2     2     1     1     0     0     0     0
     0     0     0     0     0     0     0     0     0     2     2     0     0

コメントで尋ねられたように、行列 a に 3 つの次元がある場合、3 番目の次元に沿って結果を合計する必要があります。

sum(cell2mat(arrayfun(@(b) sum(A == b,1),nonzeros(unique(A)), 'UniformOutput', false)),3)
于 2012-07-23T08:12:09.520 に答える
1

これは、1 つの関数呼び出しで実行できます。

Res = histc(A, 1:3);

期待どおりの結果:

Res =
     1     2     1     0     0     0     0     0     0     0     0     0     0
     0     0     0     1     1     2     2     1     1     0     0     0     0
     0     0     0     0     0     0     0     0     0     2     2     0     0
于 2012-07-29T20:37:13.937 に答える
0

SPARSE 関数を使用した別の代替手段 ( ACCUMARRAY を使用した@GuntherStruyfの 2 番目のソリューションと同様)

c = repmat(1:size(A,2), [size(A,1) 1]);
M = full(sparse(A(:)+1, c(:), 1));
M = M(2:end,:);

結果:

M =
     1     2     1     0     0     0     0     0     0     0     0     0     0
     0     0     0     1     1     2     2     1     1     0     0     0     0
     0     0     0     0     0     0     0     0     0     2     2     0     0
于 2012-07-29T20:44:39.543 に答える