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

Matlab 如何计算矩阵中每列值的编号,matlab,matrix,counting,Matlab,Matrix,Counting,我有矩阵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的值出现次数:即B的每一行包含了ii在A的相应列中出现的次数。数字0可以忽略 例如:在A的第二列中,只有数字1出现,具体来说是两次->因此B1,2=2和2=0 对于我的示例矩阵A,输出应该是 Res = [ 1 2 1 0 0 0 0 0 0 0 0 0 0; 0 0 0 1 1 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的值出现次数:即B的每一行包含了ii在A的相应列中出现的次数。数字0可以忽略

例如:在A的第二列中,只有数字1出现,具体来说是两次->因此B1,2=2和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 ];
你可以用

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)
你可以用

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)

这也是一个机会

可惜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 如果你有一个三维的输入矩阵,最简单的方法是先把它转换成二维矩阵,然后用上面的方法处理它。以下代码执行此转换:

% 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

这也是一个机会

可惜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 如果你有一个三维的输入矩阵,最简单的方法是先把它转换成二维矩阵,然后用上面的方法处理它。以下代码执行此转换:

% 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

您可以通过一个函数调用执行此操作:

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

您可以通过一个函数调用执行此操作:

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

另一种方法是使用稀疏函数,类似于使用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

另一种方法是使用稀疏函数,类似于使用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

你能澄清一下吗?举个例子,我不明白你在问什么。你能澄清一下吗?举个例子,我不明白你在问什么。但是如果A有超过1个值矩阵,我的意思是val:,:,1…val:,:,2 ext。我如何修改你的代码?那么你必须计算结果的和。请看我的最新答案。集合,我仍然不能尝试使用你的代码。我的意思是,我有一个矩阵A,它有一些值val:,:,1…val:,:,n,我想知道矩阵A的每个值。你知道我的意思吗?@FebriDwiLaksono先生:请原谅,但实际上我不明白你的意思。但是如果A有一个以上的值矩阵,我的意思是val:,:,1…val:,2.如何修改您的代码?然后您必须计算结果的总和。请看我的最新答案。集合,我仍然不能尝试使用你的代码。我的意思是,我有一个矩阵A,它有一些值val:,:,1…val:,:,n,我想知道矩阵A的每个值。你知道我的意思吗?@FebriDwiLaksono:请原谅,但实际上我不明白你的意思。Struyf,如果我想用你的代码计算三维矩阵A,我该怎么做?那你想要什么?你现在看的不是一个横截面而不是一个柱吗?@GuntherStruyf:+1 ACCUMARRAY是计算MR时的go to函数。Struyf,如果我想用你的代码计算三维矩阵A,我该怎么做?那你想要什么?你现在看的不是一个横截面而不是一个柱吗?@GuntherStruyf:+1 ACCUMARRAY是进行计数时的go to函数