matlab中的快速索引映射
Fast index mapping in matlab
我遇到以下问题:
给定一个矩阵 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。
关于如何加快程序的任何想法?
如果我没理解错的话,在你的例子中你想要:
A_new = [ 1 2 2 3 3 ;
2 2 2 4 5 ]
所以只需计算一个查找 table (lookup
) 这样您就可以执行以下操作:
A_new = lookup(A);
所以在你的情况下,lookup
将是:
[ 1 2 3 0 0 0 4 0 5 ]
我将把生成它的过程留作 reader 的练习。
方法一(不推荐)
这应该很快,但它使用更多内存:
[~, A_new] = max(bsxfun(@eq, A(:).', unique(A(:))));
A_new = reshape(A_new, size(A));
这是如何工作的?
首先A
被线性化为一个向量(A(:)
)。此外,计算包含 A
的唯一值的向量 (unique(A(:))
)。从这两个向量生成一个矩阵(bsxfun
),其中 A
的每个条目都与每个唯一值进行比较。这样,对于 A
的每个条目,我们知道它是否等于 first 唯一值,或 second 唯一值,等等。对于您问题中给出的 A
,该矩阵是
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
因此,例如,条目 (2,3) 中的值 1
表示 A(:)
的第三个值等于 second 的唯一值A
(即2
)。右下角条目 (5,10) 中的 1
表示 A(:)
的第十个值是 第五个 唯一值 A
(即 9
).
现在第二个输出max
is used to extract the row position of the 1
value in each columnn (i.e. to obtain the numbers indicating "second", "fifth" etc in the above example)). These are the desired results. It only remains to reshape
他们变成了A
的形状。
方法 2(推荐)
unique
的第三个输出做你想要的:
[~, ~, labels] = unique(A);
A_new = reshape(labels, size(A));
我遇到以下问题: 给定一个矩阵 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。
关于如何加快程序的任何想法?
如果我没理解错的话,在你的例子中你想要:
A_new = [ 1 2 2 3 3 ;
2 2 2 4 5 ]
所以只需计算一个查找 table (lookup
) 这样您就可以执行以下操作:
A_new = lookup(A);
所以在你的情况下,lookup
将是:
[ 1 2 3 0 0 0 4 0 5 ]
我将把生成它的过程留作 reader 的练习。
方法一(不推荐)
这应该很快,但它使用更多内存:
[~, A_new] = max(bsxfun(@eq, A(:).', unique(A(:))));
A_new = reshape(A_new, size(A));
这是如何工作的?
首先A
被线性化为一个向量(A(:)
)。此外,计算包含 A
的唯一值的向量 (unique(A(:))
)。从这两个向量生成一个矩阵(bsxfun
),其中 A
的每个条目都与每个唯一值进行比较。这样,对于 A
的每个条目,我们知道它是否等于 first 唯一值,或 second 唯一值,等等。对于您问题中给出的 A
,该矩阵是
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
因此,例如,条目 (2,3) 中的值 1
表示 A(:)
的第三个值等于 second 的唯一值A
(即2
)。右下角条目 (5,10) 中的 1
表示 A(:)
的第十个值是 第五个 唯一值 A
(即 9
).
现在第二个输出max
is used to extract the row position of the 1
value in each columnn (i.e. to obtain the numbers indicating "second", "fifth" etc in the above example)). These are the desired results. It only remains to reshape
他们变成了A
的形状。
方法 2(推荐)
unique
的第三个输出做你想要的:
[~, ~, labels] = unique(A);
A_new = reshape(labels, size(A));