matlab中的快速索引映射

时间:2015-01-13 22:29:19

标签: performance matlab matrix

我有以下问题: 给定矩阵A

A = [ 1 2 2 3 3 ;
      2 2 2 7 9 ]

其中矩阵内的唯一数字序列不连续。在这个例子中

unique(A) = [ 1 2 3 7 9 ]. % [ 4 5 6 8 ] are missing

我想计算相同的矩阵,但是使用连续的序列,例如

unique(A_new) = [ 1 2 3 4 5 ];

我提出了以下解决方案

T = [ unique(A), [ 1:numel(unique(A)) ]' ];

A_new = zeros(size(A));

for i = 1:size(T,1)
  A_new( A == T(i,1) ) = T(i,2);
end

速度非常慢:我必须使用的矩阵A的大小为200x400x300,此矩阵中的唯一元素数量为33406.

关于如何加快程序的任何想法?

2 个答案:

答案 0 :(得分:1)

如果我理解正确,在你想要的例子中:

A_new = [ 1 2 2 3 3 ;
          2 2 2 4 5 ]

所以只需计算一个查找表(lookup),然后就可以了:

A_new = lookup(A);

因此,在您的情况下,lookup将是:

[ 1 2 3 0 0 0 4 0 5 ]

我将把这个过程留给读者作为练习。

答案 1 :(得分:1)

方法1(不推荐)

这应该非常快,但它会占用更多内存:

[~, A_new] = max(bsxfun(@eq, A(:).', unique(A(:))));
A_new = reshape(A_new, size(A));

这是如何运作的?

首先将A线性化为向量(A(:))。此外,计算包含唯一值A的向量(unique(A(:)))。从这两个向量中生成矩阵(使用bsxfun),其中A的每个条目与每个唯一值进行比较。这样,对于A的每个条目,我们知道它是否等于第一个唯一值,或第二个唯一值等。对于{{1}在你的问题中给出,该矩阵是

A

例如,条目(2,3)中的值 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 表示1的第三个值等于A(:)第二个唯一值(即A)。右下方条目(5,10)中的2表示1的第十个值是第五个唯一值A(:)(即{ {1}})。

现在max的第二个输出用于提取每个列中A值的行位置(即获取表示" second 的数字"," 第五个"等在上面的例子中))。这些都是理想的结果。只有reshape它们仍为9的形状。

方法2(推荐)

unique的第三个输出符合您的要求:

1