如何在矩阵中计算每列值的编号

时间:2012-07-23 07:52:40

标签: matlab matrix counting

我有Matrix 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的每一B行包含多少次{{1发生在A的相应列中。数字0可以被忽略。

例如:在A的第2列中,仅出现数字1,具体为两次 - >因此B(1,2)= 2而B(其他,2)= 0。

对于我的示例矩阵A,输出应为

ii

4 个答案:

答案 0 :(得分:2)

这也是(under-appreciatedaccumarray

的机会
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

太糟糕了,只有在一次通话中,准确无法完成所有这一切:(

修改

在一个准确的电话中得到了一切: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

如果您有一个三维输入矩阵,最简单的方法是首先将其转换为二维矩阵,然后使用上述方法对其进行处理。以下代码执行此转换:

% 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

答案 1 :(得分: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)

答案 2 :(得分: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

答案 3 :(得分: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