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的值出现次数:即每iiB包含iiA的相应列中出现的次数。数字0可以忽略。

例如:在 A 的第 2 列中,只有数字 1 出现,具体两次 --> 因此 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 不能一次性完成所有操作:(

编辑

一次 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,:)

编辑2

如果您有一个 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 具有三个维度,则需要沿第三个维度对结果求和:

sum(cell2mat(arrayfun(@(b) sum(A == b,1),nonzeros(unique(A)), 'UniformOutput', false)),3)
于 2012-07-23T08:12:09.520 回答
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 函数的另一种选择(类似于@GuntherStruyf使用 ACCUMARRAY 的第二个解决方案)

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 回答