我正在创建一个Matlab程序来处理包含有限整数(不必是连续的(的数据数组。假设我的数据数组是A,我需要首先找到A的唯一值,这形成了一个向量B,我必须计算A中每个唯一值的出现次数,这给出了另一个向量C。最后,我需要一个向量E,它的长度与A相同,但E的第I个元素的值用k = A(i)
计算为E(i) = C(k)
我有如下代码来创建B和C:
A=[5 5 1 1 3 1 3 11 9 6 -2];
[B, ia, ic]=unique(A);
C = accumarray(ic,1);
A可能是一个大矢量,A的元素可能非常不同,范围很广,我想知道是否有任何矢量化方法来生成数组E,而不是下面的循环方法
E = zeros(size(A));
for n=1:length(E)
k=find(B==A(n));
E(n) = C(k);
end
正如您所说,要计算E
的值,您需要计算B
中对应于A
中每个元素的索引,其中A == B
是非正式的。这显然是行不通的,因为A
和B
的大小不同。但我们可以通过将事物视为二维网格来获得我们想要的东西。转换其中一个向量并将其相等。
A == B.'
% or for older versions of MATLAB (won't implicitly expand the different sized variables)
bsxfun(@eq, A, B.')
ans =
7×11 logical array
0 0 0 0 0 0 0 0 0 0 1
0 0 1 1 0 1 0 0 0 0 0
0 0 0 0 1 0 1 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1 0 0 0
% to help visualise
% A = [5 5 1 1 3 1 3 11 9 6 -2];
% B = [-2 1 3 5 6 9 11];
您可以看到,对于每一列,1的位置告诉我们可以在向量B
的A
中找到该元素。我们可以使用find
来获得每个1的行索引,并用它来计算E.
[indices, ~] = find(A == B.');
E = C(indices);
最终结果
如果你想用一行代码来计算,你可以使用以下
A=[5 5 1 1 3 1 3 11 9 6 -2];
[B, ia, ic]=unique(A);
C = accumarray(ic,1);
E = C(mod(find(B.' == A)-1, length(B))+1).';
% or for older versions of MATLAB
E = C(mod(find(bsxfun(@eq, A, B.'))-1, length(B))+1).';