6

给定一个整数向量,例如:

X = [1 2 3 4 5 1 2]

我想找到一种非常快速的方法来计算具有 2 个元素的唯一组合的数量。

在这种情况下,两个数字的组合是:

[1 2] (occurs twice)
[2 3] (occurs once) 
[3 4] (occurs once) 
[4 5] (occurs once) 
[5 1] (occurs once) 

就目前而言,我目前在 MATLAB 中执行以下操作

X = [1 2 3 4 5 1 2];
N = length(X)
X_max = max(X);
COUNTS = nan(X_max); %store as a X_max x X_max matrix

for i = 1:X_max

    first_number_indices   = find(X==1)
    second_number_indices = first_number_indices + 1;
    second_number_indices(second_number_indices>N) = [] %just in case last entry = 1
    second_number_vals = X(second_number_indices);

   for j = 1:X_max
        COUNTS(i,j) = sum(second_number_vals==j)
   end
end

有没有更快/更智能的方式来做到这一点?

4

2 回答 2

12

这是一个超级快速的方法:

>> counts = sparse(x(1:end-1),x(2:end),1)
counts =
   (5,1)        1
   (1,2)        2
   (2,3)        1
   (3,4)        1
   (4,5)        1

您可以简单地转换为完整矩阵:full(counts)


这是使用的等效解决方案accumarray

>> counts = accumarray([x(1:end-1);x(2:end)]', 1)
counts =
     0     2     0     0     0
     0     0     1     0     0
     0     0     0     1     0
     0     0     0     0     1
     1     0     0     0     0
于 2013-05-08T08:38:55.593 回答
1

编辑: @Amro 提供了一个更好的解决方案(嗯,在绝大多数情况下更好,我怀疑如果我的方法MaxX非常大并且X包含零,我的方法会更好地工作 - 这是因为零的存在将排除使用sparsewhile一个大的MaxX会减慢accumarray方法,因为它会创建一个大小为 MaxX 乘 MaxX 的矩阵)。

编辑:感谢@EitanT 指出可以使用accumarray.

以下是我将如何解决它:

%Generate some random data
T = 20;
MaxX = 3;
X = randi(MaxX, T, 1);

%Get the unique combinations and an index. Note, I am assuming X is a column vector.
[UniqueComb, ~, Ind] = unique([X(1:end-1), X(2:end)], 'rows');
NumComb = size(UniqueComb, 1);

%Count the number of occurrences of each combination
Count = accumarray(Ind, 1);

现在所有唯一的连续两个元素组合都存储在 中UniqueComb,而每个唯一组合的相应计数存储在Count.

于 2013-05-08T05:59:29.677 回答